Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
|
d43468edb9 | 2 months ago |
@ -1,5 +1,33 @@
|
||||
UniLife开发进度与计划.md
|
||||
UniLife接口文档.md
|
||||
UniLife项目文档.md
|
||||
文档说明.md
|
||||
.idea/
|
||||
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/
|
||||
|
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ApifoxUploaderProjectSetting">
|
||||
<option name="apiAccessToken" value="APS-Du6Eoh7CmJJcLtPBY40931ru8MEovCoV" />
|
||||
</component>
|
||||
</project>
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AugmentWebviewStateStore">
|
||||
<option name="stateMap">
|
||||
<map>
|
||||
<entry key="CHAT_STATE" value="eyJjdXJyZW50Q29udmVyc2F0aW9uSWQiOiJjZmRkMmFjMy02YjgyLTQ5MWUtODc0YS1iOTU2MTM4NTJjODAiLCJjb252ZXJzYXRpb25zIjp7IjcxNjQ2OWJkLTU0MWUtNDZkYi1hODhlLTk2MDE1NDk4NDczYiI6eyJpZCI6IjcxNjQ2OWJkLTU0MWUtNDZkYi1hODhlLTk2MDE1NDk4NDczYiIsImNyZWF0ZWRBdElzbyI6IjIwMjUtMDUtMDVUMDQ6NTk6MTguNjg2WiIsImxhc3RJbnRlcmFjdGVkQXRJc28iOiIyMDI1LTA1LTA1VDA0OjU5OjE4LjY4NloiLCJjaGF0SGlzdG9yeSI6W10sImZlZWRiYWNrU3RhdGVzIjp7fSwidG9vbFVzZVN0YXRlcyI6e30sImRyYWZ0RXhjaGFuZ2UiOnsicmVxdWVzdF9tZXNzYWdlIjoiIiwicmljaF90ZXh0X2pzb25fcmVwciI6eyJ0eXBlIjoiZG9jIiwiY29udGVudCI6W3sidHlwZSI6InBhcmFncmFwaCJ9XX0sInN0YXR1cyI6ImRyYWZ0In0sInJlcXVlc3RJZHMiOltdLCJpc1Bpbm5lZCI6ZmFsc2UsImlzU2hhcmVhYmxlIjpmYWxzZSwiZXh0cmFEYXRhIjp7Imhhc0RpcnR5RWRpdHMiOmZhbHNlfSwicGVyc29uYVR5cGUiOjB9LCJjZmRkMmFjMy02YjgyLTQ5MWUtODc0YS1iOTU2MTM4NTJjODAiOnsiaWQiOiJjZmRkMmFjMy02YjgyLTQ5MWUtODc0YS1iOTU2MTM4NTJjODAiLCJjcmVhdGVkQXRJc28iOiIyMDI1LTA1LTA1VDA0OjU5OjE4Ljg0NloiLCJsYXN0SW50ZXJhY3RlZEF0SXNvIjoiMjAyNS0wNS0wNVQwNDo1OToxOC44NDZaIiwiY2hhdEhpc3RvcnkiOltdLCJmZWVkYmFja1N0YXRlcyI6e30sInRvb2xVc2VTdGF0ZXMiOnt9LCJkcmFmdEV4Y2hhbmdlIjp7InJlcXVlc3RfbWVzc2FnZSI6IiIsInJpY2hfdGV4dF9qc29uX3JlcHIiOnsidHlwZSI6ImRvYyIsImNvbnRlbnQiOlt7InR5cGUiOiJwYXJhZ3JhcGgifV19LCJzdGF0dXMiOiJkcmFmdCJ9LCJyZXF1ZXN0SWRzIjpbXSwiaXNQaW5uZWQiOmZhbHNlLCJpc1NoYXJlYWJsZSI6ZmFsc2UsImV4dHJhRGF0YSI6eyJoYXNEaXJ0eUVkaXRzIjpmYWxzZX0sInBlcnNvbmFUeXBlIjowfX0sImFnZW50RXhlY3V0aW9uTW9kZSI6Im1hbnVhbCIsImlzQWdlbnRFZGl0c0NvbGxhcHNlZCI6dHJ1ZSwic29ydENvbnZlcnNhdGlvbnNCeSI6Imxhc3RNZXNzYWdlVGltZXN0YW1wIn0=" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="true" />
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="unilife-server" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="unilife@localhost" uuid="9c6c9710-15d0-4710-8fca-930cc43549e9">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:3306/unilife</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="0@127.0.0.1" uuid="a9faee19-21f5-4be8-a112-2b0ac06aaaaf">
|
||||
<driver-ref>redis</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<imported>true</imported>
|
||||
<remarks>$PROJECT_DIR$/unilife-server/src/main/resources/application.yml</remarks>
|
||||
<jdbc-driver>jdbc.RedisDriver</jdbc-driver>
|
||||
<jdbc-url>jdbc:redis://127.0.0.1:6379/0</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="UniLife@localhost" uuid="82d366b7-3273-49cc-8ccc-6fef4a2d408d">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<imported>true</imported>
|
||||
<remarks>$PROJECT_DIR$/unilife-server/src/main/resources/application.yml</remarks>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:3306/UniLife?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/unilife-server/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/unilife-server/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://maven.aliyun.com/repository/public" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/backend/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/unilife-server/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/unilife.iml" filepath="$PROJECT_DIR$/.idea/unilife.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/unilife-server/src/main/resources/db/init.sql" dialect="MySQL" />
|
||||
</component>
|
||||
</project>
|
@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.9 KiB |
@ -1,23 +1,11 @@
|
||||
<template>
|
||||
<HeaderBar/>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import HeaderBar from './components/HeaderBar.vue'
|
||||
import LogPage from './components/LogPage.vue';
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<template>
|
||||
<LogPage/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
/* 设置 body 背景渐变,清除异常布局设置 */
|
||||
body{
|
||||
height: 100%;
|
||||
width:100%;
|
||||
|
||||
/*弹性布局,水平垂直居中*/
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
/*渐变背景*/
|
||||
background: linear-gradient(200deg, #f3e7e9, #e3eeff);
|
||||
}
|
||||
</style>
|
||||
|
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 231 KiB |
Before Width: | Height: | Size: 34 KiB |
@ -1,118 +0,0 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border:none;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
|
||||
|
||||
/*除了LogPage以外的按钮尽量使用这里的样式*/
|
||||
.btn {
|
||||
outline:none;
|
||||
padding: 10px 24px;
|
||||
margin:10px;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #9370DB;
|
||||
color: white;
|
||||
box-shadow: 0 4px 10px rgba(147, 112, 219, 0.3);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #8a63d2;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: #e6e6fa;
|
||||
color: #666;
|
||||
box-shadow: 0 4px 10px rgba(230, 230, 250, 0.3);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: #dcdcdc;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/*信息展示在card上*/
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
min-height: 100vh;
|
||||
min-width: 100vw;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content:center;
|
||||
align-items:center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const images = [
|
||||
new URL('@/assets/logo-carousel/1.jpeg', import.meta.url).href,
|
||||
new URL('@/assets/logo-carousel/2.png', import.meta.url).href,
|
||||
new URL('@/assets/logo-carousel/3.jpg', import.meta.url).href
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-carousel :interval="3000" height="300px" arrow="hover">
|
||||
<el-carousel-item v-for="(img, i) in images" :key="i">
|
||||
<img :src="img" class="carousel-img" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.carousel-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
@ -1,101 +0,0 @@
|
||||
<script setup>
|
||||
import { House, Cloudy, User, Cpu, Message, HomeFilled, MessageBox, Calendar } from '@element-plus/icons-vue'
|
||||
import {useRoute} from 'vue-router'
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class ="header-bar" >
|
||||
<!-- 左侧图标组 -->
|
||||
<div class="left-icons">
|
||||
<router-link to="/unilifeHome" class="icon-btn" title="首页">
|
||||
<el-icon class="icon-btn" :size="24">
|
||||
<HomeFilled />
|
||||
</el-icon>
|
||||
</router-link>
|
||||
<router-link to="/cloud" class="icon-btn" title="资料分享">
|
||||
<el-icon class="icon-btn" :size="24">
|
||||
<MessageBox />
|
||||
</el-icon>
|
||||
</router-link>
|
||||
<router-link to="/self" class="icon-btn" title="日程">
|
||||
<el-icon class = "icon-btn" :size="24">
|
||||
<Calendar />
|
||||
</el-icon>
|
||||
</router-link>
|
||||
<router-link to="/assistant" class="icon-btn" title="AI助手">
|
||||
<el-icon class = "icon-btn" :size="24">
|
||||
<Cpu />
|
||||
</el-icon>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!-- 右侧部分 -->
|
||||
<div class="right-section">
|
||||
<router-link to="/message" class="icon-btn" title="消息">
|
||||
<Message size="24" />
|
||||
</router-link>
|
||||
<router-link to="/personal" class="user-entry" title="个人主页">
|
||||
<span>个人主页</span>
|
||||
</router-link>
|
||||
<router-link to="/log" class="icon-btn" title="登录">
|
||||
<el-icon class = "icon-btn" :size="24">
|
||||
<User />
|
||||
</el-icon>
|
||||
</router-link>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<style scoped>
|
||||
.header-bar {
|
||||
height: 70px;
|
||||
width: 100%;
|
||||
background: #ead1fb;
|
||||
position:absolute;
|
||||
top: 0;
|
||||
left:0;
|
||||
padding:0;
|
||||
margin:0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.header-bar--personal {
|
||||
background: linear-gradient(to top, #c9e4ff, #fad0c4);
|
||||
}
|
||||
|
||||
.left-icons,
|
||||
.right-section {
|
||||
padding:50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
margin: 0 10px;
|
||||
color: #606266;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.icon-btn:hover {
|
||||
transform: scale(1.1);
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.user-entry {
|
||||
margin-left: 12px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@ -1,26 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{ title: string; link: string }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-link :to="link" class="hot-topic-item">
|
||||
{{ title }}
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.hot-topic-item {
|
||||
display: block;
|
||||
background-color: #fbefff;
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #e4d4ff;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,41 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
post: {
|
||||
title: string
|
||||
tags: string[]
|
||||
excerpt: string
|
||||
link: string
|
||||
}
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-link :to="post.link" class="post-card">
|
||||
<h3>{{ post.title }}</h3>
|
||||
<div class="tags">
|
||||
<el-tag v-for="(tag, i) in post.tags" :key="i" type="info">{{ tag }}</el-tag>
|
||||
</div>
|
||||
<p>{{ post.excerpt }}</p>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.post-card {
|
||||
display: block;
|
||||
padding: 16px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||||
transition: transform 0.2s;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.tags {
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,27 +0,0 @@
|
||||
import request from "../../src/utils/request"
|
||||
|
||||
|
||||
export function useEmailCode(){
|
||||
const sendEmailCode = async(email:string) =>
|
||||
{
|
||||
return await request.post('/user/code',
|
||||
{
|
||||
params:{email:email}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const verifyEmailCode = async(email:string,code:string) =>
|
||||
{
|
||||
return await request.post('users/login/code',
|
||||
{
|
||||
params:{email:email,code:code}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return{
|
||||
sendEmailCode,
|
||||
verifyEmailCode
|
||||
}
|
||||
}
|
@ -1,16 +1,5 @@
|
||||
import { createApp } from 'vue'
|
||||
import '@/assets/style/style.css'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import router from './routers/routers'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(ElementPlus)
|
||||
app.use(router)
|
||||
for(const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
app.mount('#app')
|
||||
createApp(App).mount('#app')
|
||||
|
@ -1,57 +0,0 @@
|
||||
import type { RouteRecord, RouteRecordRaw } from 'vue-router';
|
||||
import { createWebHashHistory, createRouter,createWebHistory } from 'vue-router';
|
||||
import LogPage from '../views/LogPage.vue';
|
||||
import Personal from '@/components/Personal.vue';
|
||||
import Manager from '@/views/AcountManager.vue';
|
||||
import PersonalHome from '@/views/Home.vue';
|
||||
import ForumHome from '@/views/ForumHome.vue';
|
||||
|
||||
const routes:Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/log',
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'NotFound',
|
||||
component: () => import('@/views/404.vue'),
|
||||
},
|
||||
{
|
||||
path:'/log',
|
||||
name: 'LogPage',
|
||||
component: LogPage
|
||||
},
|
||||
{
|
||||
path:'/personal',
|
||||
name: 'Personal',
|
||||
component: Personal,
|
||||
children: [
|
||||
{
|
||||
path:'',
|
||||
name:'Home',
|
||||
component:PersonalHome,
|
||||
},
|
||||
{
|
||||
path:'manager',
|
||||
name: 'Manager',
|
||||
component:Manager,
|
||||
},
|
||||
{
|
||||
path:'ai',
|
||||
redirect: '/personal',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path:'/uniLifeHome',
|
||||
name: 'ForumHome',
|
||||
component: ForumHome,
|
||||
}
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes
|
||||
});
|
||||
|
||||
export default router;
|
@ -0,0 +1,79 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: 'http://localhost:8080',
|
||||
timeout: 5000
|
||||
});
|
||||
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
console.log("前端发送信息");
|
||||
return config;
|
||||
}
|
||||
else
|
||||
{ console.log("没有token");
|
||||
return config;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
console.log("后端返回信息");
|
||||
return response.data;
|
||||
},
|
||||
error => {
|
||||
// 对响应错误做些什么
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default service;
|
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 224 KiB |
Before Width: | Height: | Size: 207 KiB |
Before Width: | Height: | Size: 148 KiB |
Before Width: | Height: | Size: 181 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 179 KiB |
Before Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 419 KiB |
@ -1,155 +1,111 @@
|
||||
<?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">
|
||||
<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>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>unilife-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>backend</name>
|
||||
<description>backend</description>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<spring-boot.version>3.4.3</spring-boot.version>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<spring-boot.version>2.7.6</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>3.0.4</version>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>javax.persistence-api</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MySQL Connector -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.0.33</version>
|
||||
<version>8.2.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.36</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- IP2Region -->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Hutool -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.16</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Knife4j - OpenAPI3 with Jakarta -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>3.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Mail -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
<groupId>org.apache.tomcat.maven</groupId>
|
||||
<artifactId>tomcat6-maven-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.24</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- 编译器插件 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Spring Boot 插件 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<configuration>
|
||||
<mainClass>com.example.unilife.BackendApplication</mainClass>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>repackage</id>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
@ -0,0 +1,32 @@
|
||||
package com.unilife.controller;
|
||||
|
||||
import com.unilife.common.result.Result;
|
||||
import com.unilife.model.dto.LogDTO;
|
||||
import com.unilife.model.dto.LoginDTO;
|
||||
import com.unilife.service.UserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.RestController;
|
||||
|
||||
@Api(tags = "用户管理")
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@ApiOperation(value = "用户注册")
|
||||
@PostMapping("register")
|
||||
public Result register(@RequestBody LoginDTO loginDTO) {
|
||||
return userService.register(loginDTO);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "用户登录")
|
||||
@PostMapping("login")
|
||||
public Result login(@RequestBody LogDTO logDTO) { return userService.login(logDTO); }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.unilife.mapper;
|
||||
|
||||
import com.unilife.model.entity.User;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface UserMapper {
|
||||
void insert(User user);
|
||||
User FindByEmail(@Param("email") String email, @Param("password") String password);
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.unilife.model.vo;
|
||||
|
||||
import com.unilife.model.entity.User;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LogVO {
|
||||
private String username;
|
||||
private String email;
|
||||
private String nickname;
|
||||
private String studentId;
|
||||
private String department;
|
||||
private String major;
|
||||
private String grade;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.unilife.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginVO {
|
||||
private Integer id;
|
||||
private String username;
|
||||
private String nickname;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.unilife.service;
|
||||
|
||||
import com.unilife.common.result.Result;
|
||||
import com.unilife.model.dto.LogDTO;
|
||||
import com.unilife.model.dto.LoginDTO;
|
||||
import com.unilife.model.entity.User;
|
||||
|
||||
|
||||
public interface UserService {
|
||||
Result register(LoginDTO loginDTO);
|
||||
Result login(LogDTO logDTO);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.unilife.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.unilife.common.result.Result;
|
||||
import com.unilife.mapper.UserMapper;
|
||||
import com.unilife.model.dto.LogDTO;
|
||||
import com.unilife.model.dto.LoginDTO;
|
||||
import com.unilife.model.entity.User;
|
||||
import com.unilife.model.vo.LogVO;
|
||||
import com.unilife.model.vo.LoginVO;
|
||||
import com.unilife.service.UserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public Result register(LoginDTO loginDTO) {
|
||||
User user = new User();
|
||||
BeanUtil.copyProperties(loginDTO,user);
|
||||
userMapper.insert(user);
|
||||
LoginVO loginVO = new LoginVO();
|
||||
return Result.success(loginVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result login(LogDTO logDTO) {
|
||||
User user = new User();
|
||||
BeanUtil.copyProperties(logDTO,user);//将登录的前端传来的消息拷贝给这个user
|
||||
User getuser = userMapper.FindByEmail(user.getEmail(),user.getPassword());
|
||||
if(getuser == null)
|
||||
{
|
||||
return Result.error(logDTO,"用户不存在,登录失败!");
|
||||
}
|
||||
if(!user.getPassword().equals(getuser.getPassword()))
|
||||
{
|
||||
return Result.error(logDTO,"密码错误,登录失败!");
|
||||
}
|
||||
LogVO logVO = new LogVO();
|
||||
return Result.success(logVO);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.unilife.mapper.UserMapper">
|
||||
<resultMap id="userResultMap" type="com.unilife.model.entity.User">
|
||||
<result column="email" property="email"/>
|
||||
<result column="password" property="password"/>
|
||||
</resultMap>
|
||||
<insert id="insert" parameterType="com.unilife.model.entity.User" useGeneratedKeys="true" keyProperty="id">
|
||||
INSERT INTO users (
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
nickname,
|
||||
avatar,
|
||||
bio,
|
||||
gender,
|
||||
student_id,
|
||||
department,
|
||||
major,
|
||||
grade,
|
||||
points,
|
||||
role,
|
||||
status,
|
||||
is_verified,
|
||||
login_ip,
|
||||
login_time
|
||||
) VALUES (
|
||||
#{username},
|
||||
#{email},
|
||||
#{password},
|
||||
#{nickname},
|
||||
#{avatar},
|
||||
#{bio},
|
||||
#{gender},
|
||||
#{studentId},
|
||||
#{department},
|
||||
#{major},
|
||||
#{grade},
|
||||
#{points},
|
||||
#{role},
|
||||
#{status},
|
||||
#{isVerified},
|
||||
#{loginIp},
|
||||
#{loginTime}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<select id="FindByEmail" resultMap="userResultMap">
|
||||
select email,password
|
||||
from users
|
||||
where email = #{email} and password = #{password}
|
||||
</select>
|
||||
</mapper>
|
@ -1,33 +0,0 @@
|
||||
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/
|
@ -1,7 +0,0 @@
|
||||
package com.unilife.common.constant;
|
||||
|
||||
|
||||
public class RedisConstant {
|
||||
public static final String LOGIN_EMAIL_KEY="login:email:";
|
||||
public static final String LOGIN_EMAIL_LIMIT_KEY = "login:email:limit:";
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.unilife.config;
|
||||
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class SwaggerConfig {
|
||||
@Bean
|
||||
public OpenAPI customOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info().title("UniLife API").version("1.0.0"));
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.unilife.config;
|
||||
|
||||
import com.unilife.interceptor.JwtInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Autowired
|
||||
private JwtInterceptor jwtInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(jwtInterceptor).addPathPatterns("/**")
|
||||
.excludePathPatterns(
|
||||
"/users/login",
|
||||
"/users/register",
|
||||
"/users/code",
|
||||
"/users/login/code",
|
||||
"/swagger-resources/**",
|
||||
"/v3/api-docs/**",
|
||||
"/doc.html",
|
||||
"/webjars/**",
|
||||
"/favicon.ico",
|
||||
"/knife4j/**"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("*") // 允许所有来源,生产环境建议限制为特定域名
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.allowedHeaders("*")
|
||||
.allowCredentials(true)
|
||||
.maxAge(3600);
|
||||
}
|
||||
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package com.unilife.controller;
|
||||
|
||||
import com.unilife.common.result.Result;
|
||||
import com.unilife.model.entity.Category;
|
||||
import com.unilife.service.CategoryService;
|
||||
import com.unilife.utils.BaseContext;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "分类管理")
|
||||
@RestController
|
||||
@RequestMapping("/categories")
|
||||
@Slf4j
|
||||
public class CategoryController {
|
||||
|
||||
@Autowired
|
||||
private CategoryService categoryService;
|
||||
|
||||
@Operation(summary = "获取分类详情")
|
||||
@GetMapping("/{id}")
|
||||
public Result<?> getCategoryDetail(@PathVariable("id") Long categoryId) {
|
||||
return categoryService.getCategoryDetail(categoryId);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取分类列表")
|
||||
@GetMapping
|
||||
public Result<?> getCategoryList(
|
||||
@RequestParam(value = "status", required = false) Byte status) {
|
||||
return categoryService.getCategoryList(status);
|
||||
}
|
||||
|
||||
@Operation(summary = "创建分类")
|
||||
@PostMapping
|
||||
public Result<?> createCategory(@RequestBody Category category) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
|
||||
// 检查用户权限(只有管理员可以创建分类)
|
||||
// 实际项目中应该从用户服务获取用户角色信息
|
||||
// 这里简化处理,假设已经检查了权限
|
||||
|
||||
return categoryService.createCategory(category);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新分类")
|
||||
@PutMapping("/{id}")
|
||||
public Result<?> updateCategory(
|
||||
@PathVariable("id") Long categoryId,
|
||||
@RequestBody Category category) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
|
||||
// 检查用户权限(只有管理员可以更新分类)
|
||||
// 实际项目中应该从用户服务获取用户角色信息
|
||||
// 这里简化处理,假设已经检查了权限
|
||||
|
||||
return categoryService.updateCategory(categoryId, category);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除分类")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<?> deleteCategory(@PathVariable("id") Long categoryId) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
|
||||
// 检查用户权限(只有管理员可以删除分类)
|
||||
// 实际项目中应该从用户服务获取用户角色信息
|
||||
// 这里简化处理,假设已经检查了权限
|
||||
|
||||
return categoryService.deleteCategory(categoryId);
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package com.unilife.controller;
|
||||
|
||||
import com.unilife.common.result.Result;
|
||||
import com.unilife.model.dto.CreateCourseDTO;
|
||||
import com.unilife.service.CourseService;
|
||||
import com.unilife.utils.BaseContext;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "课程管理")
|
||||
@RestController
|
||||
@RequestMapping("/courses")
|
||||
@Slf4j
|
||||
public class CourseController {
|
||||
|
||||
@Autowired
|
||||
private CourseService courseService;
|
||||
|
||||
@Operation(summary = "创建课程")
|
||||
@PostMapping
|
||||
public Result<?> createCourse(@RequestBody CreateCourseDTO createCourseDTO) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.createCourse(userId, createCourseDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取课程详情")
|
||||
@GetMapping("/{id}")
|
||||
public Result<?> getCourseDetail(@PathVariable("id") Long courseId) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.getCourseDetail(courseId, userId);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户的所有课程")
|
||||
@GetMapping
|
||||
public Result<?> getCourseList() {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.getCourseList(userId);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户在指定星期几的课程")
|
||||
@GetMapping("/day/{dayOfWeek}")
|
||||
public Result<?> getCourseListByDayOfWeek(@PathVariable("dayOfWeek") Byte dayOfWeek) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.getCourseListByDayOfWeek(userId, dayOfWeek);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新课程")
|
||||
@PutMapping("/{id}")
|
||||
public Result<?> updateCourse(
|
||||
@PathVariable("id") Long courseId,
|
||||
@RequestBody CreateCourseDTO createCourseDTO) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.updateCourse(courseId, userId, createCourseDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除课程")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<?> deleteCourse(@PathVariable("id") Long courseId) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.deleteCourse(courseId, userId);
|
||||
}
|
||||
|
||||
@Operation(summary = "检查课程时间冲突")
|
||||
@GetMapping("/check-conflict")
|
||||
public Result<?> checkCourseConflict(
|
||||
@RequestParam("dayOfWeek") Byte dayOfWeek,
|
||||
@RequestParam("startTime") String startTime,
|
||||
@RequestParam("endTime") String endTime,
|
||||
@RequestParam(value = "excludeCourseId", required = false) Long excludeCourseId) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return courseService.checkCourseConflict(userId, dayOfWeek, startTime, endTime, excludeCourseId);
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
package com.unilife.controller;
|
||||
|
||||
import com.unilife.common.result.Result;
|
||||
import com.unilife.model.dto.EmailDTO;
|
||||
import com.unilife.model.dto.LoginDTO;
|
||||
import com.unilife.model.dto.LoginEmailDTO;
|
||||
import com.unilife.model.dto.RegisterDTO;
|
||||
import com.unilife.model.dto.UpdateEmailDTO;
|
||||
import com.unilife.model.dto.UpdatePasswordDTO;
|
||||
import com.unilife.model.dto.UpdateProfileDTO;
|
||||
import com.unilife.model.vo.LoginVO;
|
||||
import com.unilife.service.UserService;
|
||||
import com.unilife.utils.BaseContext;
|
||||
import com.unilife.utils.JwtUtil;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
@Tag(name = "用户管理")
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
@Slf4j
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
@Operation(summary = "用户注册")
|
||||
@PostMapping("register")
|
||||
public Result<?> register(@RequestBody RegisterDTO registerDTO, HttpServletRequest request) {
|
||||
return userService.register(registerDTO, request);
|
||||
}
|
||||
|
||||
@Operation(summary = "用户登录")
|
||||
@PostMapping("login")
|
||||
public Result<?> login(@RequestBody LoginDTO loginDTO, HttpServletRequest request) {
|
||||
Result<?> login = userService.login(loginDTO, request);
|
||||
LoginVO vo = (LoginVO) login.getData();
|
||||
if (vo == null) {
|
||||
return login;
|
||||
}
|
||||
Long id = vo.getId();
|
||||
String token = jwtUtil.generateToken(id);
|
||||
vo.setToken(token);
|
||||
BaseContext.setId(id);
|
||||
return Result.success(vo);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取邮箱验证码")
|
||||
@PostMapping("code")
|
||||
public Result<?> getCode(@RequestBody EmailDTO emailDto, HttpServletRequest request) {
|
||||
String email = emailDto.getEmail();
|
||||
log.debug("收到的原始邮箱: {}", email);
|
||||
return userService.sendVerificationCode(email, request);
|
||||
}
|
||||
|
||||
@Operation(summary = "邮箱验证码登录")
|
||||
@PostMapping("login/code")
|
||||
public Result<?> loginWithEmailCode(@RequestBody LoginEmailDTO loginEmailDTO, HttpServletRequest request) {
|
||||
Result<?> login = userService.loginWithEmail(loginEmailDTO, request);
|
||||
LoginVO vo = (LoginVO) login.getData();
|
||||
if (vo == null) {
|
||||
return login;
|
||||
}
|
||||
Long id = vo.getId();
|
||||
String token = jwtUtil.generateToken(id);
|
||||
vo.setToken(token);
|
||||
BaseContext.setId(id);
|
||||
return Result.success(vo);
|
||||
}
|
||||
|
||||
// 用户信息管理相关API
|
||||
|
||||
@Operation(summary = "获取用户个人信息")
|
||||
@GetMapping("info")
|
||||
public Result<?> getUserProfile() {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return userService.getUserProfile(userId);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户个人信息")
|
||||
@PutMapping("profile")
|
||||
public Result<?> updateUserProfile(@RequestBody UpdateProfileDTO profileDTO) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return userService.updateUserProfile(userId, profileDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改用户密码")
|
||||
@PutMapping("password")
|
||||
public Result<?> updatePassword(@RequestBody UpdatePasswordDTO passwordDTO) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return userService.updatePassword(userId, passwordDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "上传用户头像")
|
||||
@PostMapping("avatar")
|
||||
public Result<?> updateAvatar(@RequestParam("file") MultipartFile file) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return userService.updateAvatar(userId, file);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户邮箱")
|
||||
@PutMapping("email")
|
||||
public Result<?> updateEmail(@RequestBody UpdateEmailDTO emailDTO) {
|
||||
// 从当前上下文获取用户ID
|
||||
Long userId = BaseContext.getId();
|
||||
if (userId == null) {
|
||||
return Result.error(401, "未登录");
|
||||
}
|
||||
return userService.updateEmail(userId, emailDTO);
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.unilife.interceptor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.unilife.utils.BaseContext;
|
||||
import com.unilife.utils.JwtUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class JwtInterceptor implements HandlerInterceptor {
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
log.info("JwtInterceptor preHandle");
|
||||
|
||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||
return true; // 直接允许通过,不检查 token
|
||||
}
|
||||
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
|
||||
if(StrUtil.isBlank(authHeader)){
|
||||
response.setStatus(401);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 处理Bearer token格式
|
||||
String token = authHeader;
|
||||
if(authHeader.startsWith("Bearer ")){
|
||||
token = authHeader.substring(7);
|
||||
}
|
||||
log.info("Extracted token:{}", token);
|
||||
|
||||
boolean verified = jwtUtil.verifyToken(token);
|
||||
if (!verified) {
|
||||
response.setStatus(401);
|
||||
return false;
|
||||
}
|
||||
|
||||
//从token中获取userid并存入threadlocal
|
||||
Long userId = jwtUtil.getUserIdFromToken(token);
|
||||
if(userId == null) {
|
||||
response.setStatus(401);
|
||||
return false;
|
||||
}
|
||||
BaseContext.setId(userId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
BaseContext.removeId();
|
||||
}
|
||||
}
|