Compare commits
4 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
d3cd2613f5 | 2 months ago |
|
|
fad3483e59 | 2 months ago |
|
|
1ab35bbf0c | 2 months ago |
|
|
8d948426fe | 2 months ago |
@ -1,33 +0,0 @@
|
||||
GCC RUNTIME LIBRARY EXCEPTION
|
||||
|
||||
Version 3.1, 31 March 2009
|
||||
|
||||
General information: http://www.gnu.org/licenses/gcc-exception.html
|
||||
Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception.
|
||||
|
||||
When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library.
|
||||
|
||||
"GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF.
|
||||
|
||||
"GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC.
|
||||
|
||||
"Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation.
|
||||
|
||||
The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors.
|
||||
|
||||
A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process.
|
||||
|
||||
1. Grant of Additional Permission.
|
||||
|
||||
You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules.
|
||||
|
||||
2. No Weakening of GCC Copyleft.
|
||||
|
||||
The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC.
|
||||
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 441 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 931 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 270 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 344 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 135 KiB |
@ -0,0 +1,22 @@
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- study_analysis
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
jobs:
|
||||
sonarqube:
|
||||
name: SonarQube
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
# The analysis requires to retrieve dependencies and build successfully
|
||||
- name: Build
|
||||
run: <mark><commands_to_build_your_project></mark>
|
||||
- name: SonarQube Scan
|
||||
uses: SonarSource/sonarqube-scan-action@v6
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
@ -0,0 +1,53 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
.vscode/
|
||||
.VSCodeCounter/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins-dependencies
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
/coverage/
|
||||
/lib/data/user_data.json
|
||||
*.g.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
#linux server
|
||||
/backend/spring.log
|
||||
/backend/nohup.out
|
||||
@ -0,0 +1,45 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "a402d9a4376add5bc2d6b1e33e53edaae58c07f8"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
- platform: android
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
- platform: ios
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
- platform: linux
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
- platform: macos
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
- platform: web
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
- platform: windows
|
||||
create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
@ -0,0 +1,28 @@
|
||||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at https://dart.dev/lints.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
@ -0,0 +1,14 @@
|
||||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
.cxx/
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/to/reference-keystore
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
@ -0,0 +1,49 @@
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("kotlin-android")
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.tutoring_software"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId = "com.example.tutoring_software"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||
minSdk = flutter.minSdkVersion
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
// 添加以下配置以支持64位架构
|
||||
ndk {
|
||||
abiFilters += "arm64-v8a"
|
||||
abiFilters += "x86_64"
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@ -0,0 +1,52 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 添加这一行网络权限 -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<!-- 可选:允许检查网络状态 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:label="软件工程家教软件"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:taskAffinity=""
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
|
||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@ -0,0 +1,6 @@
|
||||
package com.example.tutoring_software;
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
After Width: | Height: | Size: 544 B |
|
After Width: | Height: | Size: 442 B |
|
After Width: | Height: | Size: 721 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<!-- 允许访问阿里云服务器 -->
|
||||
<domain includeSubdomains="true">8.140.222.2</domain>
|
||||
<!-- 可选:允许访问本地开发服务器 -->
|
||||
<domain includeSubdomains="true">127.0.0.1</domain>
|
||||
<domain includeSubdomains="true">10.0.2.2</domain> <!-- Android模拟器访问本地主机 -->
|
||||
<domain includeSubdomains="true">192.168.18.128</domain> <!-- 虚拟机IP -->
|
||||
</domain-config>
|
||||
<base-config cleartextTrafficPermitted="false" />
|
||||
</network-security-config>
|
||||
@ -0,0 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@ -0,0 +1,25 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url=uri("https://maven.aliyun.com/repository/public/") }
|
||||
}
|
||||
}
|
||||
|
||||
val newBuildDir: Directory =
|
||||
rootProject.layout.buildDirectory
|
||||
.dir("../../build")
|
||||
.get()
|
||||
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||
|
||||
subprojects {
|
||||
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
||||
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(":app")
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
||||
@ -0,0 +1,26 @@
|
||||
pluginManagement {
|
||||
val flutterSdkPath =
|
||||
run {
|
||||
val properties = java.util.Properties()
|
||||
file("local.properties").inputStream().use { properties.load(it) }
|
||||
val flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
|
||||
flutterSdkPath
|
||||
}
|
||||
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "8.9.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
||||
}
|
||||
|
||||
include(":app")
|
||||
@ -0,0 +1,2 @@
|
||||
/mvnw text eol=lf
|
||||
*.cmd text eol=crlf
|
||||
@ -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,3 @@
|
||||
wrapperVersion=3.3.4
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
|
||||
@ -0,0 +1,295 @@
|
||||
#!/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.4
|
||||
#
|
||||
# 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:]'
|
||||
}
|
||||
|
||||
scriptDir="$(dirname "$0")"
|
||||
scriptName="$(basename "$0")"
|
||||
|
||||
# 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 <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.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${scriptName#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
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
actualDistributionDir=""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
|
||||
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$distributionUrlNameMain"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
# enable globbing to iterate over items
|
||||
set +f
|
||||
for dir in "$TMP_DOWNLOAD_DIR"/*; do
|
||||
if [ -d "$dir" ]; then
|
||||
if [ -f "$dir/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$(basename "$dir")"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
set -f
|
||||
fi
|
||||
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
verbose "Contents of $TMP_DOWNLOAD_DIR:"
|
||||
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
|
||||
die "Could not find Maven distribution directory in extracted archive"
|
||||
fi
|
||||
|
||||
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
||||
@ -0,0 +1,189 @@
|
||||
<# : 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.4
|
||||
@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 -eq $False) { "/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_M2_PATH = "$HOME/.m2"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
|
||||
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
$MAVEN_WRAPPER_DISTS = $null
|
||||
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
|
||||
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
|
||||
} else {
|
||||
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
|
||||
}
|
||||
|
||||
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::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
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
$actualDistributionDir = ""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
|
||||
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
|
||||
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
|
||||
$actualDistributionDir = $distributionUrlNameMain
|
||||
}
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if (!$actualDistributionDir) {
|
||||
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
|
||||
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
|
||||
if (Test-Path -Path $testPath -PathType Leaf) {
|
||||
$actualDistributionDir = $_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$actualDistributionDir) {
|
||||
Write-Error "Could not find Maven distribution directory in extracted archive"
|
||||
}
|
||||
|
||||
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -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,100 @@
|
||||
<?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.5.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.tutoring-software</groupId>
|
||||
<artifactId>backend</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>backend</name>
|
||||
<description>家教软件的后端</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.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>3.5.7</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-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-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- 添加 Apache Commons Lang 依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.18.0</version>
|
||||
</dependency>
|
||||
<!-- 添加 SLF4J 日志依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,15 @@
|
||||
package com.tutoring_software.backend;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.tutoring_software.backend.uid_management.mapper")
|
||||
public class BackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BackendApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.tutoring_software.backend;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.service.PhoneNumberUidService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class HelloWorldController {
|
||||
|
||||
@Autowired
|
||||
private PhoneNumberUidService phoneNumberUidService;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HelloWorldController.class);
|
||||
|
||||
@GetMapping("/hello")
|
||||
public String helloWorld() {
|
||||
String phoneNumber = "133124448678";
|
||||
Long uid = 12336633L;
|
||||
try {
|
||||
boolean success = phoneNumberUidService.savePhoneNumberUid(phoneNumber, uid);
|
||||
if (success) {
|
||||
return "保存成功: 电话号码" + phoneNumber + " 与 UID " + uid + " 已关联";
|
||||
} else {
|
||||
return "保存失败,请重试";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("保存电话号码与UID映射关系时发生错误", e);
|
||||
return "保存时发生错误: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 存储电话号码和UID的映射关系
|
||||
// * 调用示例: POST /hello/save-phone-uid?phoneNumber=13812345678&uid=123456
|
||||
// */
|
||||
// @PostMapping("/hello/save-phone-uid")
|
||||
// public String savePhoneNumberUid(@RequestParam String phoneNumber, @RequestParam Long uid) {
|
||||
// try {
|
||||
// boolean success = phoneNumberUidService.savePhoneNumberUid(phoneNumber, uid);
|
||||
// if (success) {
|
||||
// return "保存成功: 电话号码" + phoneNumber + " 与 UID " + uid + " 已关联";
|
||||
// } else {
|
||||
// return "保存失败,请重试";
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// return "保存时发生错误: " + e.getMessage();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据电话号码查询对应的UID
|
||||
// * 调用示例: GET /hello/get-uid-by-phone?phoneNumber=13812345678
|
||||
// */
|
||||
// @GetMapping("/hello/get-uid-by-phone")
|
||||
// public String getUidByPhoneNumber(@RequestParam String phoneNumber) {
|
||||
// try {
|
||||
// return phoneNumberUidService.getByPhoneNumber(phoneNumber) != null
|
||||
// ? "查询结果: 电话号码" + phoneNumber + " 对应的UID是 " + phoneNumberUidService.getByPhoneNumber(phoneNumber).getUid()
|
||||
// : "未找到该电话号码对应的UID";
|
||||
// } catch (Exception e) {
|
||||
// return "查询时发生错误: " + e.getMessage();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据UID查询对应的电话号码
|
||||
// * 调用示例: GET /hello/get-phone-by-uid?uid=123456
|
||||
// */
|
||||
// @GetMapping("/hello/get-phone-by-uid")
|
||||
// public String getPhoneByUid(@RequestParam Long uid) {
|
||||
// try {
|
||||
// return phoneNumberUidService.getByUid(uid) != null
|
||||
// ? "查询结果: UID " + uid + " 对应的电话号码是 " + phoneNumberUidService.getByUid(uid).getPhoneNumber()
|
||||
// : "未找到该UID对应的电话号码";
|
||||
// } catch (Exception e) {
|
||||
// return "查询时发生错误: " + e.getMessage();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.tutoring_software.backend.uid_generate;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.tutoring_software.backend.uid_generate.UidGenerator;
|
||||
import com.tutoring_software.backend.uid_generate.exception.UidGenerateException;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/uid")
|
||||
public class UidController {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UidController.class);
|
||||
|
||||
@Autowired
|
||||
private UidGenerator uidGenerator;
|
||||
|
||||
/**
|
||||
* 生成一个唯一的UID
|
||||
*/
|
||||
@GetMapping("/generate")
|
||||
public Result<Long> generateUid() {
|
||||
try {
|
||||
long uid = uidGenerator.getUID();
|
||||
LOGGER.info("Generated UID: {}", uid);
|
||||
return Result.success(uid);
|
||||
} catch (UidGenerateException e) {
|
||||
LOGGER.error("Failed to generate UID", e);
|
||||
return Result.error("Failed to generate UID: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析UID
|
||||
*/
|
||||
@GetMapping("/parse")
|
||||
public Result<String> parseUid(Long uid) {
|
||||
if (uid == null) {
|
||||
return Result.error("UID cannot be null");
|
||||
}
|
||||
|
||||
try {
|
||||
String parsed = uidGenerator.parseUID(uid);
|
||||
LOGGER.info("Parsed UID: {}", parsed);
|
||||
return Result.success(parsed);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to parse UID", e);
|
||||
return Result.error("Failed to parse UID: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 统一响应结果封装类
|
||||
public static class Result<T> {
|
||||
private int code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
private Result(int code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<>(200, "Success", data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String message) {
|
||||
return new Result<>(500, message, null);
|
||||
}
|
||||
|
||||
// Getters and setters
|
||||
public int getCode() { return code; }
|
||||
public void setCode(int code) { this.code = code; }
|
||||
public String getMessage() { return message; }
|
||||
public void setMessage(String message) { this.message = message; }
|
||||
public T getData() { return data; }
|
||||
public void setData(T data) { this.data = data; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.tutoring_software.backend.uid_generate;
|
||||
|
||||
import com.tutoring_software.backend.uid_generate.exception.UidGenerateException;
|
||||
|
||||
public interface UidGenerator {
|
||||
//获取一个唯一的ID
|
||||
long getUID() throws UidGenerateException;
|
||||
|
||||
//将生成的UID解析为构成元素的详细信息
|
||||
String parseUID(long uid);
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.tutoring_software.backend.uid_generate;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.tutoring_software.backend.uid_generate.UidGenerator;
|
||||
import com.tutoring_software.backend.uid_generate.impl.DefaultUidGenerator;
|
||||
import com.tutoring_software.backend.uid_generate.worker.WorkerIdAssigner;
|
||||
|
||||
@Configuration
|
||||
public class UidGeneratorConfig {
|
||||
|
||||
@Bean
|
||||
public UidGenerator uidGenerator(WorkerIdAssigner workerIdAssigner) {
|
||||
DefaultUidGenerator uidGenerator = new DefaultUidGenerator();
|
||||
uidGenerator.setWorkerIdAssigner(workerIdAssigner);
|
||||
// 可以根据需要调整位分配策略
|
||||
uidGenerator.setTimeBits(28); // 时间位数
|
||||
uidGenerator.setWorkerBits(22); // 工作节点位数
|
||||
uidGenerator.setSeqBits(13); // 序列号位数
|
||||
uidGenerator.setEpochStr("2024-01-01"); // 设置纪元时间
|
||||
return uidGenerator;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.tutoring_software.backend.uid_generate.exception;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
public class UidGenerateException extends RuntimeException{
|
||||
//序列化版本标识符,用于确保序列化和反序列化的版本兼容性
|
||||
@Serial
|
||||
private static final long serialVersionUID = -27048199131316992L;
|
||||
|
||||
//父类无参构造方法
|
||||
public UidGenerateException() {
|
||||
super();
|
||||
}
|
||||
|
||||
//带错误消息和原因的构造函数
|
||||
public UidGenerateException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
//支持带有错误消息的构造函数
|
||||
public UidGenerateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
//支持消息格式化的构造函数
|
||||
public UidGenerateException(String msgFormat, Object... args) {
|
||||
super(String.format(msgFormat, args));
|
||||
}
|
||||
|
||||
//仅仅带有异常原因的构造函数
|
||||
public UidGenerateException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.tutoring_software.backend.uid_generate.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
|
||||
public abstract class UidDateUtils {
|
||||
|
||||
public static final String DAY_PATTERN = "yyyy-MM-dd";
|
||||
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
|
||||
public static final Date DEFAULT_DATE = UidDateUtils.parseByDayPattern("1970-01-01");
|
||||
|
||||
public static Date parseByDayPattern(String str) {
|
||||
return parseDate(str, DAY_PATTERN);
|
||||
}
|
||||
|
||||
public static Date parseByDateTimePattern(String str) {
|
||||
return parseDate(str, DATETIME_PATTERN);
|
||||
}
|
||||
|
||||
public static Date parseDate(String str, String pattern) {
|
||||
try {
|
||||
return DateUtils.parseDate(str, new String[]{pattern});
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatDate(Date date, String pattern) {
|
||||
return DateFormatUtils.format(date, pattern);
|
||||
}
|
||||
|
||||
public static String formatByDayPattern(Date date) {
|
||||
if (date != null) {
|
||||
return DateFormatUtils.format(date, DAY_PATTERN);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatByDateTimePattern(Date date) {
|
||||
return DateFormatUtils.format(date, DATETIME_PATTERN);
|
||||
}
|
||||
|
||||
public static String getCurrentDayByDayPattern() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
return formatByDayPattern(cal.getTime());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.tutoring_software.backend.uid_generate.worker;
|
||||
|
||||
public interface WorkerIdAssigner {
|
||||
long assignWorkerId();
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.tutoring_software.backend.uid_management;
|
||||
|
||||
/**
|
||||
* 统一响应结果封装类
|
||||
*/
|
||||
public class Result<T> {
|
||||
private int code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
private Result(int code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<>(200, "Success", data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String message) {
|
||||
return new Result<>(500, message, null);
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public int getCode() { return code; }
|
||||
public void setCode(int code) { this.code = code; }
|
||||
public String getMessage() { return message; }
|
||||
public void setMessage(String message) { this.message = message; }
|
||||
public T getData() { return data; }
|
||||
public void setData(T data) { this.data = data; }
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.entity.CommentItem;
|
||||
import com.tutoring_software.backend.uid_management.entity.Teacher;
|
||||
import com.tutoring_software.backend.uid_management.service.CommentItemService;
|
||||
import com.tutoring_software.backend.uid_management.service.TeacherService;
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 评论控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/comment")
|
||||
public class CommentItemController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CommentItemController.class);
|
||||
|
||||
@Autowired
|
||||
private CommentItemService commentItemService;
|
||||
|
||||
@Autowired
|
||||
private TeacherService teacherService;
|
||||
|
||||
/**
|
||||
* 根据老师UID获取评论列表
|
||||
*/
|
||||
@GetMapping("/teacher/{teacherUid}")
|
||||
public Result<List<CommentItem>> getCommentsByTeacher(@PathVariable Long teacherUid) {
|
||||
LOGGER.info("需要查询老师{}的评论列表", teacherUid);
|
||||
try {
|
||||
List<CommentItem> result = commentItemService.getCommentsByTeacherUid(teacherUid);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("No comments found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting comments by teacher UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据学生UID获取评论列表
|
||||
*/
|
||||
@GetMapping("/student/{studentUid}")
|
||||
public Result<List<CommentItem>> getCommentsByStudent(@PathVariable Long studentUid) {
|
||||
LOGGER.info("需要查询学生{}的评论列表", studentUid);
|
||||
try {
|
||||
List<CommentItem> result = commentItemService.getCommentsByStudentUid(studentUid);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("No comments found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting comments by student UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存评论
|
||||
*/
|
||||
@PostMapping("/save")
|
||||
public Result<String> saveComment(@RequestBody CommentItem commentItem) {
|
||||
LOGGER.info("保存评论: 学生{} 评论老师{}", commentItem.getStudentUid(), commentItem.getTeacherUid());
|
||||
try {
|
||||
// 设置创建时间
|
||||
if (commentItem.getCreatedAt() == null) {
|
||||
commentItem.setCreatedAt(LocalDateTime.now());
|
||||
}
|
||||
boolean success = commentItemService.saveComment(commentItem);
|
||||
if (success) {
|
||||
LOGGER.info("成功保存评论: 学生{} 评论老师{}", commentItem.getStudentUid(), commentItem.getTeacherUid());
|
||||
// 更新老师的评论数
|
||||
Teacher teacher = teacherService.getByTeacherUid(commentItem.getTeacherUid());
|
||||
if (teacher != null) {
|
||||
double commentRating = Double.parseDouble(commentItem.getRating());
|
||||
double currentRating = teacher.getRating();
|
||||
double newRating = (currentRating * teacher.getComments() + commentRating)
|
||||
/ (teacher.getComments() + 1);
|
||||
int newComments = teacher.getComments() + 1;
|
||||
teacherService.updateTeacher(commentItem.getTeacherUid(), newRating, newComments);
|
||||
}
|
||||
return Result.success("Save successful");
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving comment", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
import com.tutoring_software.backend.uid_management.entity.EmailUid;
|
||||
import com.tutoring_software.backend.uid_management.service.EmailUidService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/email-uid")
|
||||
public class EmailUidController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EmailUidController.class);
|
||||
|
||||
@Autowired
|
||||
private EmailUidService emailUidService;
|
||||
|
||||
@GetMapping("/by-email/{email}")
|
||||
public Result<EmailUid> getByEmail(@PathVariable String email) {
|
||||
try {
|
||||
EmailUid result = emailUidService.getByEmail(email);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("Email not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by email", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/by-uid/{uid}")
|
||||
public Result<EmailUid> getByUid(@PathVariable Long uid) {
|
||||
try {
|
||||
EmailUid result = emailUidService.getByUid(uid);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Result<EmailUid> save(@RequestBody EmailUid emailUid) {
|
||||
try {
|
||||
boolean success = emailUidService.saveEmailUid(emailUid.getEmail(), emailUid.getUid());
|
||||
if (success) {
|
||||
return Result.success(emailUid);
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving email UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public Result<EmailUid> saveEmailUid(@RequestParam String email, @RequestParam Long uid) {
|
||||
try {
|
||||
boolean success = emailUidService.saveEmailUid(email, uid);
|
||||
if (success) {
|
||||
// 打印成功信息
|
||||
LOGGER.info("Successfully saved EmailUid: email={}, uid={}", email, uid);
|
||||
return Result.success(new EmailUid(email, uid));
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving email UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public Result<String> updateEmailUid(@RequestParam String email, @RequestParam Long uid) {
|
||||
try {
|
||||
boolean success = emailUidService.updateByEmail(email, uid);
|
||||
if (success) {
|
||||
return Result.success("Update successful");
|
||||
} else {
|
||||
return Result.error("Update failed or email not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error updating email UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete/email/{email}")
|
||||
public Result<String> deleteByEmail(@PathVariable String email) {
|
||||
try {
|
||||
boolean success = emailUidService.deleteByEmail(email);
|
||||
if (success) {
|
||||
return Result.success("Delete successful");
|
||||
} else {
|
||||
return Result.error("Delete failed or email not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error deleting by email", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete/uid/{uid}")
|
||||
public Result<String> deleteByUid(@PathVariable Long uid) {
|
||||
try {
|
||||
boolean success = emailUidService.deleteByUid(uid);
|
||||
if (success) {
|
||||
return Result.success("Delete successful");
|
||||
} else {
|
||||
return Result.error("Delete failed or UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error deleting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.entity.PhoneNumberUid;
|
||||
import com.tutoring_software.backend.uid_management.service.PhoneNumberUidService;
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/phone-uid")
|
||||
public class PhoneNumberUidController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PhoneNumberUidController.class);
|
||||
|
||||
@Autowired
|
||||
private PhoneNumberUidService phoneNumberUidService;
|
||||
|
||||
@GetMapping("/by-phone/{phoneNumber}")
|
||||
public Result<PhoneNumberUid> getByPhoneNumber(@PathVariable String phoneNumber) {
|
||||
try {
|
||||
PhoneNumberUid result = phoneNumberUidService.getByPhoneNumber(phoneNumber);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("Phone number not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by phone number", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/by-uid/{uid}")
|
||||
public Result<PhoneNumberUid> getByUid(@PathVariable Long uid) {
|
||||
try {
|
||||
PhoneNumberUid result = phoneNumberUidService.getByUid(uid);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public Result<String> savePhoneNumberUid(@RequestParam String phoneNumber, @RequestParam Long uid) {
|
||||
try {
|
||||
boolean success = phoneNumberUidService.savePhoneNumberUid(phoneNumber, uid);
|
||||
if (success) {
|
||||
// 打印成功信息
|
||||
LOGGER.info("Successfully saved PhoneNumberUid: phoneNumber={}, uid={}", phoneNumber, uid);
|
||||
return Result.success("Save successful");
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving phone number UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public Result<String> updatePhoneNumberUid(@RequestParam String phoneNumber, @RequestParam Long uid) {
|
||||
try {
|
||||
boolean success = phoneNumberUidService.updateByPhoneNumber(phoneNumber, uid);
|
||||
if (success) {
|
||||
return Result.success("Update successful");
|
||||
} else {
|
||||
return Result.error("Update failed or phone number not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error updating phone number UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete/phone/{phoneNumber}")
|
||||
public Result<String> deleteByPhoneNumber(@PathVariable String phoneNumber) {
|
||||
try {
|
||||
boolean success = phoneNumberUidService.deleteByPhoneNumber(phoneNumber);
|
||||
if (success) {
|
||||
return Result.success("Delete successful");
|
||||
} else {
|
||||
return Result.error("Delete failed or phone number not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error deleting by phone number", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete/uid/{uid}")
|
||||
public Result<String> deleteByUid(@PathVariable Long uid) {
|
||||
try {
|
||||
boolean success = phoneNumberUidService.deleteByUid(uid);
|
||||
if (success) {
|
||||
return Result.success("Delete successful");
|
||||
} else {
|
||||
return Result.error("Delete failed or UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error deleting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
import com.tutoring_software.backend.uid_management.entity.TSRelationship;
|
||||
import com.tutoring_software.backend.uid_management.service.TSRelationshipService;
|
||||
|
||||
/**
|
||||
* 师生关系控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/ts-relationship")
|
||||
public class TSRelationshipController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TSRelationshipController.class);
|
||||
|
||||
@Autowired
|
||||
private TSRelationshipService tsRelationshipService;
|
||||
|
||||
/**
|
||||
* 根据学生UID获取师生关系列表
|
||||
*/
|
||||
@GetMapping("/student/{studentUid}")
|
||||
public Result<List<TSRelationship>> getRelationshipsByStudent(@PathVariable Long studentUid) {
|
||||
LOGGER.info("需要查询学生{}的师生关系列表", studentUid);
|
||||
try {
|
||||
List<TSRelationship> result = tsRelationshipService.selectByStudentUid(studentUid);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("No relationships found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting relationships by student UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据老师UID获取师生关系列表
|
||||
*/
|
||||
@GetMapping("/teacher/{teacherUid}")
|
||||
public Result<List<TSRelationship>> getRelationshipsByTeacher(@PathVariable Long teacherUid) {
|
||||
LOGGER.info("需要查询老师{}的师生关系列表", teacherUid);
|
||||
try {
|
||||
List<TSRelationship> result = tsRelationshipService.selectByTeacherUid(teacherUid);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("No relationships found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting relationships by teacher UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据学生UID和老师UID查询特定师生关系
|
||||
*/
|
||||
@GetMapping("/check")
|
||||
public Result<TSRelationship> checkRelationship(@RequestParam Long studentUid, @RequestParam Long teacherUid) {
|
||||
LOGGER.info("检查学生{}和老师{}的关系", studentUid, teacherUid);
|
||||
try {
|
||||
TSRelationship relationship = tsRelationshipService.selectByStudentAndTeacherUid(studentUid, teacherUid);
|
||||
if (relationship != null) {
|
||||
return Result.success(relationship);
|
||||
} else {
|
||||
return Result.error("Relationship not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error checking relationship", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存师生关系
|
||||
*/
|
||||
@PostMapping("/save")
|
||||
public Result<String> saveRelationship(@RequestBody TSRelationship tsRelationship) {
|
||||
LOGGER.info("保存师生关系: 学生{} 和老师{}", tsRelationship.getStudentUid(), tsRelationship.getTeacherUid());
|
||||
try {
|
||||
boolean success = tsRelationshipService.saveRelationship(tsRelationship);
|
||||
if (success) {
|
||||
LOGGER.info("成功保存师生关系: 学生{} 和老师{}", tsRelationship.getStudentUid(), tsRelationship.getTeacherUid());
|
||||
return Result.success("Save successful");
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving relationship", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除师生关系
|
||||
*/
|
||||
@DeleteMapping("/delete")
|
||||
public Result<String> deleteRelationship(@RequestParam Long studentUid, @RequestParam Long teacherUid) {
|
||||
LOGGER.info("删除师生关系: 学生{} 和老师{}", studentUid, teacherUid);
|
||||
try {
|
||||
boolean success = tsRelationshipService.deleteRelationship(studentUid, teacherUid);
|
||||
if (success) {
|
||||
LOGGER.info("成功删除师生关系: 学生{} 和老师{}", studentUid, teacherUid);
|
||||
return Result.success("Delete successful");
|
||||
} else {
|
||||
return Result.error("Delete failed or relationship not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error deleting relationship", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
import com.tutoring_software.backend.uid_management.entity.UserAvatars;
|
||||
import com.tutoring_software.backend.uid_management.service.UserAvatarsService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/user-avatars")
|
||||
public class UserAvatarsController {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserAvatarsController.class);
|
||||
|
||||
@Autowired
|
||||
private UserAvatarsService userAvatarsService;
|
||||
|
||||
@GetMapping("/get/{uid}")
|
||||
public Result<UserAvatars> getByUid(@PathVariable String uid) {
|
||||
// 把uid转换为Long类型
|
||||
Long uidLong = Long.parseLong(uid);
|
||||
LOGGER.info("需要查询的uid为:{}", uidLong);
|
||||
try {
|
||||
UserAvatars result = userAvatarsService.getByUid(uidLong);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
// 存储头像数据
|
||||
@PostMapping("/save")
|
||||
public Result<String> saveUserAvatars(@RequestBody UserAvatars userAvatars) {
|
||||
try {
|
||||
// 首先检查用户是否已存在
|
||||
UserAvatars existingUser = userAvatarsService.getByUid(userAvatars.getUid());
|
||||
if (existingUser != null) {
|
||||
LOGGER.error("用户{}已存在,保存失败", userAvatars.getUid());
|
||||
return Result.error("User already exists"); // 返回明确的用户已存在错误
|
||||
}
|
||||
boolean success = userAvatarsService.saveUserAvatars(
|
||||
userAvatars.getUid(), userAvatars.getImageData(),
|
||||
userAvatars.getMimeType());
|
||||
if (success) {
|
||||
LOGGER.info("成功存储数据:uid={}", userAvatars.getUid());
|
||||
return Result.success("Save successful");
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving user avatar", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
// 更新头像数据
|
||||
@PutMapping("/update")
|
||||
public Result<String> updateUserAvatars(@RequestBody UserAvatars userAvatars) {
|
||||
try {
|
||||
boolean success = userAvatarsService.updateUserAvatars(
|
||||
userAvatars.getUid(), userAvatars.getImageData(),
|
||||
userAvatars.getMimeType());
|
||||
if (success) {
|
||||
LOGGER.info("成功更新用户{}的头像", userAvatars.getUid());
|
||||
return Result.success("Update successful");
|
||||
} else {
|
||||
LOGGER.warn("更新用户{}头像失败,用户不存在", userAvatars.getUid());
|
||||
return Result.error("User not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error updating user avatar", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.entity.UserDataItem;
|
||||
import com.tutoring_software.backend.uid_management.service.UserDataItemService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/user-data-item")
|
||||
public class UserDataItemController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserDataItemController.class);
|
||||
|
||||
@Autowired
|
||||
private UserDataItemService userDataItemService;
|
||||
|
||||
@GetMapping("/get/{uid}")
|
||||
public Result<UserDataItem> getByUid(@PathVariable String uid) {
|
||||
// 把uid转换为Long类型
|
||||
Long uidLong = Long.parseLong(uid);
|
||||
LOGGER.info("需要查询的uid为:{}", uidLong);
|
||||
try {
|
||||
UserDataItem result = userDataItemService.getByUid(uidLong);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public Result<String> saveUserDataItem(@RequestBody UserDataItem userDataItem) {
|
||||
try {
|
||||
// 首先检查用户是否已存在
|
||||
UserDataItem existingUser = userDataItemService.getByUid(userDataItem.getUid());
|
||||
if (existingUser != null) {
|
||||
LOGGER.error("用户{}已存在,保存失败", userDataItem.getUid());
|
||||
return Result.error("User already exists"); // 返回明确的用户已存在错误
|
||||
}
|
||||
boolean success = userDataItemService.saveUserDataItem(
|
||||
userDataItem.getUid(), userDataItem.getUsername(),
|
||||
userDataItem.getPhoneNumber(), userDataItem.getEmail(),
|
||||
userDataItem.getBirthday(), userDataItem.getRole(),
|
||||
userDataItem.getGender(), userDataItem.getPassword(),
|
||||
userDataItem.getTeachingSubjects(), userDataItem.getLearningSubjects());
|
||||
if (success) {
|
||||
LOGGER.info("成功存储数据:uid={},username={}", userDataItem.getUid(), userDataItem.getUsername());
|
||||
return Result.success("Save successful");
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving user data item", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
public Result<String> updateUserDataItem(@RequestBody UserDataItem userDataItem) {
|
||||
try {
|
||||
// 检查用户是否存在
|
||||
UserDataItem existingUser = userDataItemService.getByUid(userDataItem.getUid());
|
||||
if (existingUser == null) {
|
||||
LOGGER.error("用户{}不存在,更新失败", userDataItem.getUid());
|
||||
return Result.error("User not found");
|
||||
}
|
||||
|
||||
boolean success = userDataItemService.updateUserDataItem(
|
||||
userDataItem.getUid(), userDataItem.getUsername(),
|
||||
userDataItem.getPhoneNumber(), userDataItem.getEmail(),
|
||||
userDataItem.getBirthday(), userDataItem.getRole(),
|
||||
userDataItem.getGender(), userDataItem.getPassword(),
|
||||
userDataItem.getTeachingSubjects(), userDataItem.getLearningSubjects());
|
||||
|
||||
if (success) {
|
||||
LOGGER.info("成功更新用户数据:uid={},username={}", userDataItem.getUid(), userDataItem.getUsername());
|
||||
return Result.success("Update successful");
|
||||
} else {
|
||||
return Result.error("Update failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error updating user data item", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package com.tutoring_software.backend.uid_management.controller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.tutoring_software.backend.uid_management.Result;
|
||||
import com.tutoring_software.backend.uid_management.entity.UserSignature;
|
||||
import com.tutoring_software.backend.uid_management.service.UserSignatureService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/user-signatures")
|
||||
public class UserSignatureController {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserSignatureController.class);
|
||||
|
||||
@Autowired
|
||||
private UserSignatureService userSignatureService;
|
||||
|
||||
// 通过uid获取用户的签名
|
||||
@GetMapping("/get/{uid}")
|
||||
public Result<UserSignature> getByUid(@PathVariable String uid) {
|
||||
// 把uid转换为Long类型
|
||||
Long uidLong = Long.parseLong(uid);
|
||||
LOGGER.info("需要查询的uid为:{}", uidLong);
|
||||
try {
|
||||
UserSignature result = userSignatureService.getByUid(uidLong);
|
||||
if (result != null) {
|
||||
return Result.success(result);
|
||||
} else {
|
||||
return Result.error("UID not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error getting by UID", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
// 存储用户签名数据
|
||||
@PostMapping("/save")
|
||||
public Result<String> saveUserSignature(@RequestBody UserSignature userSignature) {
|
||||
try {
|
||||
// 首先检查用户是否已存在
|
||||
UserSignature existingUser = userSignatureService.getByUid(userSignature.getUid());
|
||||
if (existingUser != null) {
|
||||
LOGGER.error("用户{}已存在,保存失败", userSignature.getUid());
|
||||
return Result.error("User already exists"); // 返回明确的用户已存在错误
|
||||
}
|
||||
boolean success = userSignatureService.saveUserSignature(
|
||||
userSignature.getUid(), userSignature.getSignatures());
|
||||
if (success) {
|
||||
LOGGER.info("成功存储数据:uid={}", userSignature.getUid());
|
||||
return Result.success("Save successful");
|
||||
} else {
|
||||
return Result.error("Save failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error saving user signature", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
// 更新签名数据
|
||||
@PutMapping("/update")
|
||||
public Result<String> updateUserSignatures(@RequestBody UserSignature userSignature) {
|
||||
try {
|
||||
boolean success = userSignatureService.updateSignature(
|
||||
userSignature.getUid(), userSignature.getSignatures());
|
||||
if (success) {
|
||||
LOGGER.info("成功更新用户{}的签名", userSignature.getUid());
|
||||
return Result.success("Update successful");
|
||||
} else {
|
||||
LOGGER.warn("更新用户{}签名失败,用户不存在", userSignature.getUid());
|
||||
return Result.error("User not found");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error updating user signature", e);
|
||||
return Result.error("Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
@TableName("comments")
|
||||
public class CommentItem {
|
||||
//BIGSERVAL
|
||||
@TableId(type=IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/*字段*/
|
||||
//学生UID
|
||||
//老师UID
|
||||
@TableField("student_uid")
|
||||
private Long studentUid;
|
||||
@TableField("teacher_uid")
|
||||
private Long teacherUid;
|
||||
|
||||
//评论的内容 VarChar(1000)
|
||||
//评分 Char(1)
|
||||
//评论的时间 TIMESTAMP、
|
||||
//评论的学科VarChar(40)
|
||||
@TableField("content")
|
||||
private String content;
|
||||
@TableField("rating")
|
||||
private String rating;
|
||||
@TableField("created_at")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createdAt;
|
||||
@TableField("subject")
|
||||
private String subject;
|
||||
|
||||
//构造函数
|
||||
public CommentItem() {
|
||||
}
|
||||
public CommentItem(Long studentUid, Long teacherUid, String content, String rating, LocalDateTime createdAt, String subject) {
|
||||
this.studentUid = studentUid;
|
||||
this.teacherUid = teacherUid;
|
||||
this.content = content;
|
||||
this.rating = rating;
|
||||
this.createdAt = createdAt;
|
||||
this.subject = subject;
|
||||
}
|
||||
//getter和setter
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public Long getStudentUid() {
|
||||
return studentUid;
|
||||
}
|
||||
public void setStudentUid(Long studentUid) {
|
||||
this.studentUid = studentUid;
|
||||
}
|
||||
public Long getTeacherUid() {
|
||||
return teacherUid;
|
||||
}
|
||||
public void setTeacherUid(Long teacherUid) {
|
||||
this.teacherUid = teacherUid;
|
||||
}
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
public String getRating() {
|
||||
return rating;
|
||||
}
|
||||
public void setRating(String rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@TableName("email_id")
|
||||
public class EmailUid {
|
||||
@TableId(type=IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
//字段
|
||||
@TableField("email")
|
||||
private String email;
|
||||
@TableField("uid") // UID字段
|
||||
private Long uid;
|
||||
|
||||
//构造函数
|
||||
public EmailUid() {}
|
||||
public EmailUid(String email, Long uid){
|
||||
this.email = email;
|
||||
this.uid = uid;
|
||||
}
|
||||
//getter和setter
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Long getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(Long uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@TableName("phone_number_id")
|
||||
public class PhoneNumberUid {
|
||||
//主键字段
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
//字段
|
||||
@TableField("phone_number") // 手机号字段
|
||||
private String phoneNumber;
|
||||
@TableField("uid") // UID字段
|
||||
private Long uid;
|
||||
|
||||
// 构造函数
|
||||
public PhoneNumberUid() {}
|
||||
public PhoneNumberUid(String phoneNumber, Long uid){
|
||||
this.phoneNumber = phoneNumber;
|
||||
this.uid = uid;
|
||||
}
|
||||
//getter和setter
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
}
|
||||
|
||||
public Long getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(Long uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@TableName("teacher_student_relationship")
|
||||
public class TSRelationship {
|
||||
// 主键字段 - BIGSERIAL类型
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
// 学生UID字段
|
||||
@TableField("student_uid")
|
||||
private Long studentUid;
|
||||
|
||||
// 老师UID字段
|
||||
@TableField("teacher_uid")
|
||||
private Long teacherUid;
|
||||
|
||||
//学科选择关系char(6)
|
||||
@TableField("subject")
|
||||
private int subject;
|
||||
|
||||
//学情分析
|
||||
@TableField("analysis")
|
||||
private String analysis;
|
||||
|
||||
// 构造函数
|
||||
public TSRelationship() {}
|
||||
|
||||
public TSRelationship(Long studentUid, Long teacherUid) {
|
||||
this.studentUid = studentUid;
|
||||
this.teacherUid = teacherUid;
|
||||
}
|
||||
|
||||
// getter和setter方法
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getStudentUid() {
|
||||
return studentUid;
|
||||
}
|
||||
|
||||
public void setStudentUid(Long studentUid) {
|
||||
this.studentUid = studentUid;
|
||||
}
|
||||
|
||||
public Long getTeacherUid() {
|
||||
return teacherUid;
|
||||
}
|
||||
|
||||
public void setTeacherUid(Long teacherUid) {
|
||||
this.teacherUid = teacherUid;
|
||||
}
|
||||
|
||||
public int getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(int subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getAnalysis() {
|
||||
return analysis;
|
||||
}
|
||||
|
||||
public void setAnalysis(String analysis) {
|
||||
this.analysis = analysis;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@TableName("teachers")
|
||||
public class Teacher {
|
||||
// BIGSERIAL 自增id
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
// 老师的uid
|
||||
@TableField("teacher_uid")
|
||||
private Long teacherUid;
|
||||
|
||||
// 老师的评分rating
|
||||
@TableField("rating")
|
||||
private double rating;
|
||||
|
||||
// 老师的评价数量 int comments
|
||||
@TableField("comments")
|
||||
private int comments;
|
||||
|
||||
// 无参构造函数
|
||||
public Teacher() {
|
||||
}
|
||||
|
||||
// 全参构造函数
|
||||
public Teacher(Long teacherUid, double rating, int comments) {
|
||||
this.teacherUid = teacherUid;
|
||||
this.rating = rating;
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
// getter 和 setter 方法
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getTeacherUid() {
|
||||
return teacherUid;
|
||||
}
|
||||
|
||||
public void setTeacherUid(Long teacherUid) {
|
||||
this.teacherUid = teacherUid;
|
||||
}
|
||||
|
||||
public double getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
||||
public void setRating(double rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public int getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(int comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@TableName("teachers_courses")
|
||||
public class TeacherCourse {
|
||||
// BIGSERIAL 自增id
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
// 老师的uid
|
||||
@TableField("teacher_uid")
|
||||
private Long teacherUid;
|
||||
|
||||
// 老师选择教学的学科(6位整数组成的学科ID)
|
||||
@TableField("subject")
|
||||
private String subject;
|
||||
|
||||
// 无参构造函数
|
||||
public TeacherCourse() {
|
||||
}
|
||||
|
||||
// 全参构造函数
|
||||
public TeacherCourse(Long teacherUid, String subject) {
|
||||
this.teacherUid = teacherUid;
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
// getter 和 setter 方法
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getTeacherUid() {
|
||||
return teacherUid;
|
||||
}
|
||||
|
||||
public void setTeacherUid(Long teacherUid) {
|
||||
this.teacherUid = teacherUid;
|
||||
}
|
||||
|
||||
public String getSubject(){
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject){
|
||||
this.subject = subject;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,130 @@
|
||||
package com.tutoring_software.backend.uid_management.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@TableName("user_data_item")
|
||||
public class UserDataItem {
|
||||
//主键字段
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
//字段:分别为
|
||||
// uid BIGINT 不能为空
|
||||
// 用户名 varchar(100) 不能为空
|
||||
// 手机号 varchar(20) 可以为空
|
||||
// 邮箱 varchar(255) 可以为空
|
||||
// 生日 varchar(20) 可以为空
|
||||
// 身份 varchar(15) 不可为空
|
||||
//性别 varchar(10) 不可为空
|
||||
// 密码 varchar(40) 不可为空
|
||||
// 教学科目 varchar(1000) 可以为空
|
||||
// 学习科目 varchar(1000) 可以为空
|
||||
@TableField("uid")
|
||||
private Long uid;
|
||||
@TableField("username")
|
||||
private String username;
|
||||
@TableField("phone_number")
|
||||
private String phoneNumber = "";
|
||||
@TableField("email")
|
||||
private String email = "";
|
||||
@TableField("birthday")
|
||||
private String birthday = "";
|
||||
@TableField("role")
|
||||
private String role;
|
||||
@TableField("gender")
|
||||
private String gender = "隐藏";
|
||||
@TableField("password")
|
||||
private String password;
|
||||
@TableField("teaching_subjects")
|
||||
private String teachingSubjects ;
|
||||
@TableField("learning_subjects")
|
||||
private String learningSubjects ;
|
||||
|
||||
public UserDataItem(){}
|
||||
public UserDataItem(
|
||||
Long uid, String username, String phoneNumber,
|
||||
String email, String birthday, String role,
|
||||
String gender, String password,
|
||||
String teachingSubjects, String learningSubjects) {
|
||||
this.uid = uid;
|
||||
this.username = username;
|
||||
this.phoneNumber = phoneNumber;
|
||||
this.email = email;
|
||||
this.birthday = birthday;
|
||||
this.role = role;
|
||||
this.gender = gender;
|
||||
this.password = password;
|
||||
this.teachingSubjects = teachingSubjects;
|
||||
this.learningSubjects = learningSubjects;
|
||||
}
|
||||
|
||||
//getter 和 setter
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public Long getUid() {
|
||||
return uid;
|
||||
}
|
||||
public void setUid(Long uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
}
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
public String getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
public void setBirthday(String birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
public String getGender() {
|
||||
return gender;
|
||||
}
|
||||
public void setGender(String gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
public String getTeachingSubjects() {
|
||||
return teachingSubjects;
|
||||
}
|
||||
public void setTeachingSubjects(String teachingSubjects) {
|
||||
this.teachingSubjects = teachingSubjects;
|
||||
}
|
||||
public String getLearningSubjects() {
|
||||
return learningSubjects;
|
||||
}
|
||||
public void setLearningSubjects(String learningSubjects) {
|
||||
this.learningSubjects = learningSubjects;
|
||||
}
|
||||
}
|
||||