第三次提交

完善腾讯云图片存储
完善登录逻辑
完善页面显示
This commit is contained in:
陈佳彬 2024-09-22 22:25:54 +08:00
parent 8439d436b5
commit efc25bd26a
26 changed files with 3894 additions and 438 deletions

View File

@ -2,20 +2,21 @@
<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="Online-code-evaluation-system" />
<module name="oj-spring-boot" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="Online-code-evaluation-system" target="17" />
<module name="oj-spring-boot" target="1.8" />
</bytecodeTargetLevel>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="Online-code-evaluation-system" options="-parameters" />
<module name="oj-spring-boot" options="-parameters" />
</option>
</component>
</project>

12
.idea/dataSources.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@localhost" uuid="6aaf03f9-1117-4cce-acf3-09911a21dc79">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -7,5 +7,5 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

View File

@ -2,8 +2,8 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/oj-spring-boot/Online-code-evaluation-system.iml" filepath="$PROJECT_DIR$/oj-spring-boot/Online-code-evaluation-system.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/XJ-OJ.iml" filepath="$PROJECT_DIR$/.idea/XJ-OJ.iml" />
<module fileurl="file://$PROJECT_DIR$/oj-spring-boot/oj-spring-boot.iml" filepath="$PROJECT_DIR$/oj-spring-boot/oj-spring-boot.iml" />
</modules>
</component>
</project>

View File

@ -1,4 +1,4 @@
# 在线代码测评系统(第二次测试)
# 在线代码测评系统
### 开发环境
@ -19,32 +19,14 @@
![img](./images/clip_image002.gif)
```
视图层包括网站主站点和后台管理系统主站点负责向用户提供服务是用户看到的系统页面。用户可以在上面进行登录注册、个人信息管理、查看题目、编写代码、提交代码、查看测评状态、查看排名、参加竞赛、查看竞赛结果以及发布文章等主要操作。后台管理系统是专门给系统管理员使用的管理后台管理员可以在上面进行用户管理、题目管理、竞赛管理、日志管理以及查看系统运行状态等操作。视图层通过Axios与后端接口进行数据交互。
```
```
网络接口层的主要职责是接收用户的请求根据请求参数的不同做出不同的响应响应数据的格式是JSON数据。
```
```
业务层包括用户服务、题目服务、竞赛服务、代码服务、测评服务、文件服务、文章服务等功能模块。业务层主要是实现系统功能的代码部分,通过数据映射实现和数据层的交互,从而实现数据的持久化。
```
```
数据层是系统最底层也是最重要的一层系统中所有的数据均保存在数据层的MySQL服务和Redis服务中。
```
- 视图层包括网站主站点和后台管理系统主站点负责向用户提供服务是用户看到的系统页面。用户可以在上面进行登录注册、个人信息管理、查看题目、编写代码、提交代码、查看测评状态、查看排名、参加竞赛、查看竞赛结果以及发布文章等主要操作。后台管理系统是专门给系统管理员使用的管理后台管理员可以在上面进行用户管理、题目管理、竞赛管理、日志管理以及查看系统运行状态等操作。视图层通过Ajax与后端接口进行数据交互。
- 网络接口层的主要职责是接收用户的请求根据请求参数的不同做出不同的响应响应数据的格式是JSON数据。
- 业务层包括用户服务、题目服务、竞赛服务、代码服务、测评服务、文件服务、文章服务等功能模块。业务层主要是实现系统功能的代码部分,通过数据映射实现和数据层的交互,从而实现数据的持久化。
- 数据层是系统最底层也是最重要的一层系统中所有的数据均保存在数据层的MySQL服务和Redis服务中。
### 系统总体设计
```
本系统主要分为用户和管理员两个主要的模块。用户模块主要包括登录注册、个人中心、题目浏览、代码评测、竞赛参与、文章发布等多个子功能模块。管理员的功能模块包括用户管理、题目管理、测评管理、竞赛管理、文章管理等。本系统详细的功能模块划分图如图所示。
```
![img](./images/clip_image002-1695122986088-2.gif)
@ -58,7 +40,7 @@ Compile Error编译错误。用户提交的代码中有语法错误无法
Partial Accepted部分测评用例通过。表面用户提交的源代码可以通过部分测评用例还有一部分测评用例无法通过需要用户考虑其他的可能性。
Accepted通过。用户提交的源代码经过测试后通过了所有的测评用例用户解决了该题目。
Accepted通过。用户提交的源代码经过测试后通过了所有的测评用例用户解决了该题目。
Wrong Answer答案错误。表示用户提交的源代码的输出结果错误没有通过任何一个测评用例。
@ -92,8 +74,6 @@ System Error系统错误。在进行代码测评时测评机器发送错
![img](./images/clip_image002.jpg)
###### 图4.1 用户注册页面
2) 个人中心
个人中心主要用于向用户展示自己的个人信息。同时用户还可以进行个人资料的编辑和重置密码等操作。如图所示是系统个人中心页面。
@ -155,3 +135,35 @@ System Error系统错误。在进行代码测评时测评机器发送错
管理员可以对文章进行管理。实现了查看文章列表、删除文章等功能。文章管理页面如图所示。
![img](./images/clip_image020.jpg)
# 开发过程
## 整体架构
- 后端服务
- 后端管理界面
- 前端显示界面
### 后端服务
#### 技术选型
- SpringBoot
- MySql
- Redis
### 后端管理界面
#### 技术选型
- Html、Css、 JavaScript
- thymeleaf
- 组件库 [Layui](https://layui.dev/docs/2/base.html)
### 前端显示界面
#### 技术选型
- Vue
- 组件库 [Element-plus](https://element-plus.org/zh-CN/component/overview.html)
- 文本编辑器 TODO

3196
log/onlineoj.log Normal file

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,16 @@
Date: 30/11/2023 13:19:41
*/
SET NAMES utf8mb4;
# 先创建数据库
# CREATE DATABASE XJ_OJ;
# USE XJ_OJ;
# 如果是MySql8.0以上的版本遇到报错可以尝试将 utf8_general_ci替换为utf8mb4_0900_ai_ci
# 同时将utf8替换为utf8mb4
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
@ -46,11 +55,11 @@ CREATE TABLE `code` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '代码id',
`user_id` int NOT NULL,
`problem_id` int NOT NULL,
`code_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`code_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`create_time` datetime NULL DEFAULT NULL,
`language` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`language` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of code
@ -62,13 +71,13 @@ CREATE TABLE `code` (
DROP TABLE IF EXISTS `contest`;
CREATE TABLE `contest` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`start_time` datetime NULL DEFAULT NULL,
`end_time` datetime NULL DEFAULT NULL,
`num` int NULL DEFAULT NULL,
`status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of contest
@ -85,7 +94,7 @@ CREATE TABLE `contest_problem` (
`submit_num` int NOT NULL DEFAULT 0 COMMENT '提交数',
`solved_num` int NOT NULL DEFAULT 0 COMMENT '通过数',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of contest_problem
@ -102,7 +111,7 @@ CREATE TABLE `contest_user` (
`submit_num` int NOT NULL DEFAULT 0,
`solved_num` int NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of contest_user
@ -117,14 +126,14 @@ CREATE TABLE `evaluation` (
`user_id` int NOT NULL,
`problem_id` int NOT NULL,
`create_time` datetime NOT NULL,
`language` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`language` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`passed_test_case_num` int NOT NULL DEFAULT 0,
`all_test_case_num` int NOT NULL DEFAULT 0,
`error` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
`error` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`is_passed` int NOT NULL DEFAULT 0,
`status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of evaluation
@ -136,12 +145,12 @@ CREATE TABLE `evaluation` (
DROP TABLE IF EXISTS `file`;
CREATE TABLE `file` (
`id` int NOT NULL,
`original_filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`new_filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`original_filename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`new_filename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`date` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of file
@ -203,10 +212,10 @@ DROP TABLE IF EXISTS `test_case`;
CREATE TABLE `test_case` (
`id` int NOT NULL AUTO_INCREMENT,
`problem_id` int NOT NULL,
`input` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`output` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`input` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`output` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of test_case

View File

@ -8,15 +8,15 @@
<version>2.7.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>top.weiyuexin</groupId>
<artifactId>Online-code-evaluation-system</artifactId>
<groupId>com.cjb666</groupId>
<artifactId>XJ-OJ</artifactId>
<version>1.0.0</version>
<name>Online-code-evaluation-system</name>
<description>Online-code-evaluation-system</description>
<name>XJ-OJ</name>
<description>XJ-OJ</description>
<properties>
<java.version>17</java.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>

View File

@ -0,0 +1,26 @@
package top.weiyuexin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 全局跨域配置
*
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 覆盖所有请求
registry.addMapping("/**")
// 允许发送 Cookie
.allowCredentials(true)
// 放行哪些域名必须用 patterns否则 * 会和 allowCredentials 冲突
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("*");
}
}

View File

@ -0,0 +1,15 @@
package top.weiyuexin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.weiyuexin.interceptor.LoginInterceptor;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/index.html/**");
}
}

View File

@ -34,11 +34,12 @@ public class AdminController {
@Autowired
private ArticleService articleService;
@GetMapping("/login")
@GetMapping(value = {"/","/login"})
public String login() {
return "user/login";
}
/**
* 管理员登录
*
@ -46,13 +47,13 @@ public class AdminController {
* @param password
* @return
*/
@GetMapping("/admin/login.do/{username}/{password}")
@PostMapping("/adminLogin")
@ResponseBody
public R adminLogin(@PathVariable("username") String username,
@PathVariable("password") String password) {
public R adminLogin(String username, String password) {
User user = new User();
user.setUsername(username);
user.setPassword(password);
System.out.println(user);
// 2校验用户名和密码是否正确
user.setPassword(DigestUtil.md5Hex(user.getPassword()));
User queriedUser = userService.getByNameAndPasswordAndIsAdmin(user.getUsername(), user.getPassword());
@ -108,7 +109,7 @@ public class AdminController {
}
user.setPassword(DigestUtil.md5Hex(user.getPassword()));
user.setRegisterTime(Time.CurrentTime());
user.setPhoto("https://img.weiyuexin.top/img/picgo/2023/04/27/20230427183111.png");
user.setPhoto("");
if (userService.save(user)) {
return R.success("用户添加成功");
} else {

View File

@ -103,7 +103,7 @@ public class ArticleController {
/**
* 删除文章
*
* @param article
* @param
* @return
*/
@DeleteMapping("/{id}")

View File

@ -117,7 +117,7 @@ public class UserController {
user.setIntroduction("暂无介绍");
user.setPassword(DigestUtil.md5Hex(user.getPassword()));
user.setRegisterTime(Time.CurrentTime());
user.setPhoto("https://img.weiyuexin.top/img/picgo/2023/04/27/20230427183111.png");
user.setPhoto("");
if (userService.save(user)) {
return R.success("注册成功");
} else {
@ -173,8 +173,9 @@ public class UserController {
* @param user
* @return
*/
@PutMapping("")
public R updateUser(User user) {
@PutMapping("/modify")
public R updateUser(@RequestBody User user) {
System.out.println( user);
if (user.getPassword() != null) {
user.setPassword(DigestUtil.md5Hex(user.getPassword()));
}

View File

@ -17,7 +17,7 @@ public class ContestCron {
@Autowired
private ContestService contestService;
@Scheduled(fixedRate = 1000)
// @Scheduled(fixedRate = 1000)
public void updateContestStatus() throws ParseException {
List<Contest> contests = contestService.getAllNewContest();
for (int i = 0; i < contests.size(); i++) {

View File

@ -1,8 +1,10 @@
package top.weiyuexin.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -14,15 +16,32 @@ import javax.servlet.http.HttpServletResponse;
* @Email: 3022422894@qq.com
* @Date: 2023/4/27 17:19
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//未登录跳转到登录页
if (request.getCookies() == null || true) {
response.sendRedirect("/login");
Cookie[] cookies = request.getCookies();
String username=null;
String password=null;
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username")){
username=cookie.getValue();
}
if (cookie.getName().equals("password")){
password=cookie.getValue();
}
}
return false;
System.out.println(username+" "+password);
if (username==null || password==null){
response.sendRedirect("/login");
return false;
}
// //未登录跳转到登录页
// if (request.getCookies() == null || true) {
// response.sendRedirect("/login");
// }
return true;
}
@Override

View File

@ -8,6 +8,7 @@ import org.springframework.stereotype.Service;
import top.weiyuexin.pojo.vo.R;
import top.weiyuexin.service.EmailService;
import java.io.File;
import java.util.concurrent.TimeUnit;
/**
@ -38,6 +39,7 @@ public class EmailServiceImpl implements EmailService {
//调用HuTool中的发送验证码的方法发送验证码
try {
MailUtil.send(email,title,emailCodeContent,false);
// MailUtil.sendText(email,title,emailCodeContent, (File) null);
// 将验证码保存到Redis并设置过期时间为5分钟
redisTemplate.opsForValue().set("emailCode:"+email, String.valueOf(emailCode),60*5, TimeUnit.SECONDS);
return R.success("验证码发送成功!");

View File

@ -3,18 +3,20 @@ server:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://116.222.21.125:3306/onlineoj?useUnicode=true&characterEncoding=UTF-8&useJDBC49CompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
url: jdbc:mysql://localhost:3306/xj_oj?useUnicode=true&characterEncoding=UTF-8&useJDBC49CompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
username: root
password: weiyuexin
password: filwy3344
type: com.alibaba.druid.pool.DruidDataSource
# 配置servlet的多部分上传文件限制
servlet:
multipart:
# 设置请求的最大大小,超过此大小的请求将被拒绝
max-request-size: 100MB
# 设置单个上传文件的最大大小,超过此大小的文件将被拒绝
max-file-size: 100MB
redis:
host: 116.222.21.125
host: 192.168.200.130
port: 6379
password: weiyuexin
lettuce:
pool:
# 最大阻塞等待时间,负数表示没有限制
@ -39,11 +41,11 @@ spring:
pathmatch:
matching-strategy: ant_path_matcher
tencent:
secretId: AKID
secretKey: 1qlUzIOJ8
bucket: ap-beijing
bucketName: wyx-130
path: https://img.weiyuexin.top
secretId: AKIDRZbP5Zu1zmy45rTrRtAD8rBNgrvrb7Uo
secretKey: HMDxVr471jGesvsfHkMuInJm6OWnxueB
bucket: ap-chengdu
bucketName: xj-oj-1329750222
path: https://xj-oj-1329750222.cos.ap-chengdu.myqcloud.com
qianzui: img
qianzui-file: file
@ -76,17 +78,15 @@ knife4j:
basic:
username: root
password: root
enable: false
enable: true
openapi:
title: 在线代码测评系统官方文档
description: "在线代码测评系统 API 文档"
email: 3022422894@qq.com
concat: YuexinWei
url: https://blog.weiyuexin.top
email: 2948429338@qq.com
concat: ChenJiabin
url: https://127.0.0.1:8080/doc.html
version: v4.0.2
license: Apache 2.0
license-url: https://blog.weiyuexin.top
terms-of-service-url: https://blog.weiyuexin.top
group:
controller:
group-name: 接口

View File

@ -3,8 +3,12 @@ host = smtp.qq.com
# 邮件服务器的SMTP端口可选默认25
port = 587
# 发件人(必须正确,否则发送失败)
from = wyxweiyuexin@qq.com
from = 2948429338@qq.com
# 用户名,默认为发件人邮箱前缀
user = wyxweiyuexin
user = 2948429338@qq.com
# 密码注意某些邮箱需要为SMTP服务单独设置授权码详情查看相关帮助
pass = brsrxrunyqmxdeje
pass = rfvewkybntywdhfe
#使用 STARTTLS安全连接STARTTLS是对纯文本通信协议的扩展
starttlsEnable = true
# 需要设置为false 否则QQ邮箱测试邮件发送报错
sslEnable = false

View File

@ -1,5 +1,4 @@
body {
background-image: url(https://img.weiyuexin.top/img/picgo/2023/04/09/20230409173204.jpg);
background-position: 14px 14px;
background-repeat: no-repeat;
background-position: center center;

View File

@ -61,12 +61,12 @@
<a href="javascript:;" data-check-screen="full"><i class="fa fa-arrows-alt"></i></a>
</li>
<li class="layui-nav-item layuimini-setting">
<a href="javascript:;" id="username"></a>
<a href="javascript:;" id="username">admin</a>
<dl class="layui-nav-child">
<dd>
<a href="javascript:;" layuimini-content-href="page/user-setting.html" data-title="基本资料"
data-icon="fa fa-gears">基本资料<span class="layui-badge-dot"></span></a>
</dd>
<!-- <dd>-->
<!-- <a href="javascript:;" layuimini-content-href="page/user-setting.html" data-title="基本资料"-->
<!-- data-icon="fa fa-gears">基本资料<span class="layui-badge-dot"></span></a>-->
<!-- </dd>-->
<dd>
<a href="javascript:;" layuimini-content-href="page/user-password.html"
data-title="修改密码"
@ -76,7 +76,7 @@
<hr>
</dd>
<dd>
<a href="/user/logout" class="login-out">退出登录</a>
<a class="login-out">退出登录</a>
</dd>
</dl>
</li>
@ -163,12 +163,25 @@
'layuimini-onepage.99php.cn',
],
});
//
// $('.login-out').on("click", function () {
// layer.msg('退出登录成功', function () {
// window.location = '/login';
// });
// });
// 设置或删除Cookie
function setCookie(name, value, days) {
var expires = '';
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
}
$('.login-out').on("click", function () {
setCookie('username', '', -1);
setCookie('password', '', -1);
layer.msg('退出登录成功', function () {
window.location = '/login';
});
});
});
</script>

View File

@ -1,58 +1,175 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>登录-HENU-OJ-后台管理系统</title>
<link type="favicon" rel="shortcut icon" href="../images/pns.png">
<!-- 引入Jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<!-- 引入Layui.css -->
<link rel="stylesheet" th:href="@{/lib/layui-v2.6.3/css/layui.css}">
<!-- 引入Layui.js -->
<script th:src="@{/lib/layui-v2.6.3/layui.js}" /></script>
<script th:src="@{/js/login.js}"></script>
<link rel="stylesheet" th:href="@{/css/login.css}">
<meta charset="UTF-8">
<title>后台管理-登陆</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style>
html, body {width: 100%;height: 100%;overflow: hidden}
body {background: #1E9FFF;}
body:after {content:'';background-repeat:no-repeat;background-size:cover;-webkit-filter:blur(3px);-moz-filter:blur(3px);-o-filter:blur(3px);-ms-filter:blur(3px);filter:blur(3px);position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1;}
.layui-container {width: 100%;height: 100%;overflow: hidden}
.admin-login-background {width:360px;height:300px;position:absolute;left:50%;top:40%;margin-left:-180px;margin-top:-100px;}
.logo-title {text-align:center;letter-spacing:2px;padding:14px 0;}
.logo-title h1 {color:#1E9FFF;font-size:25px;font-weight:bold;}
.login-form {background-color:#fff;border:1px solid #fff;border-radius:3px;padding:14px 20px;box-shadow:0 0 8px #eeeeee;}
.login-form .layui-form-item {position:relative;}
.login-form .layui-form-item label {position:absolute;left:1px;top:1px;width:38px;line-height:36px;text-align:center;color:#d2d2d2;}
.login-form .layui-form-item input {padding-left:36px;}
.captcha {width:60%;display:inline-block;}
.captcha-img {display:inline-block;width:34%;float:right;}
.captcha-img img {height:34px;border:1px solid #e6e6e6;height:36px;width:100%;}
</style>
</head>
<body>
<div class="layui-form" id="loginForm">
<div class="layui-form-item">
<h1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h1>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<span class="decrib">账号:</span>
<input type="text" name="username" placeholder="请输入管理员账号" autocomplete="off" class="layui-input" id="username" required="">
<div class="layui-container">
<div class="admin-login-background">
<div class="layui-form login-form">
<form class="layui-form" action="">
<div class="layui-form-item logo-title">
<h1>LayuiMini后台登录</h1>
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-username" for="username"></label>
<input type="text" name="username" lay-verify="required|account" placeholder="用户名或者邮箱" autocomplete="off" class="layui-input" value="">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-password" for="password"></label>
<input type="password" name="password" lay-verify="required|password" placeholder="密码" autocomplete="off" class="layui-input" value="">
</div>
<div class="layui-form-item">
<label class="layui-icon layui-icon-vercode" for="captcha"></label>
<input type="text" name="captcha" lay-verify="required|captcha" placeholder="图形验证码" autocomplete="off" class="layui-input verification captcha" value="">
<div class="captcha-img">
<img id="captchaPic" src="../images/captcha.jpg">
</div>
</div>
<div class="layui-form-item">
<input type="checkbox" name="rememberMe" value="true" lay-skin="primary" title="记住密码">
</div>
<div class="layui-form-item">
<button class="layui-btn layui-btn layui-btn-normal layui-btn-fluid" lay-submit="" lay-filter="login">登 入</button>
</div>
</form>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<span class="decrib">密码:</span>
<input type="password" name="password" placeholder="请输入密码" autocomplete="off" class="layui-input" id="password" required="">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<span class="decrib">验证:</span>
<input type="text" placeholder="请输入验证码" class="input-val" autocomplete="off" required="">
<canvas id="canvas" width="100" height="44">
</canvas>
</div>
</div>
<br>
<div class="layui-form-item">
<div class="layui-input-block login">
<button class="layui-btn layui-btn-bypercent-left btn" id="submit">登 录</button> &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;
</div>
</div>
<br>
<br>
<!--<span class="forget"><a th:href="@{/user/forget}">忘记密码?</a></span>-->
</div>
</body>
<script src="../lib/jquery-3.4.1/jquery-3.4.1.min.js" charset="utf-8"></script>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script src="../lib/jq-module/jquery.particleground.min.js" charset="utf-8"></script>
<script>
layui.use(['form'], function () {
var form = layui.form,
layer = layui.layer;
</html>
// 登录过期的时候跳出ifram框架
if (top.location != self.location) top.location = self.location;
// 粒子线条背景
$(document).ready(function(){
$('.layui-container').particleground({
dotColor:'#7ec7fd',
lineColor:'#7ec7fd'
});
});
// 读取Cookie中的用户名和密码
function readCookies() {
var username = getCookie('username');
var password = getCookie('password');
if (username && password) {
$('input[name="username"]').val(username);
$('input[name="password"]').val(password);
$('input[name="rememberMe"]').prop('checked', true);
}
}
// 设置或删除Cookie
function setCookie(name, value, days) {
var expires = '';
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
}
function getCookie(name) {
var nameEQ = name + '=';
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// 进行登录操作
form.on('submit(login)', function (data) {
data = data.field;
if (data.username == '') {
layer.msg('用户名不能为空');
return false;
}
if (data.password == '') {
layer.msg('密码不能为空');
return false;
}
if (data.captcha.toUpperCase() !== 'xszg'.toUpperCase()) {
layer.msg('验证码不正确');
return false;
}
// 设置或删除Cookie
if (data.rememberMe === 'true') {
setCookie('username', data.username, 30);
setCookie('password', data.password, 30);
} else {
setCookie('username', '', -1);
setCookie('password', '', -1);
}
// 使用 jQuery 发送 AJAX 请求
$.ajax({
type: 'POST',
url: '/adminLogin',
data: {
username: data.username,
password: data.password
},
dataType: 'json',
success: function (response) {
if (response.code===200) {
layer.msg('登录成功', function () {
window.location = '../index.html';
});
} else {
layer.msg('登录失败: ' + response.msg);
}
},
error: function (jqXHR, textStatus, errorThrown) {
layer.msg('登录失败: ' + textStatus);
}
});
return false;
});
// 初始化读取Cookie
readCookies();
});
</script>
</body>
</html>

View File

@ -1,24 +1,29 @@
# oj-vue
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -8,7 +8,7 @@
</el-col>
<el-col :span="8">
<div class="link">
Copyright &nbsp;© &nbsp;2023 &nbsp;<a href="http://github.com/weiyuexin" target="_blank" class="author-link">Ginkgo</a>
Copyright &nbsp;© &nbsp;2023 &nbsp;<a href="" target="_blank" class="author-link">Ginkgo</a>
</div>
</el-col>
<el-col :span="8">
@ -41,7 +41,7 @@ export default {
<style scoped>
.footer {
width: 100%;
height: 150px;
height: 10%;
background-color: #fff;
margin-top: 30px;
position: fixed;
@ -58,14 +58,12 @@ export default {
}
.logo {
height: 100%;
margin-top: 20px;
height: 5%;
}
.logo img {
position: relative;
top: 13%;
width: 22%;
width: 15%;
text-align: center;
}
@ -74,6 +72,6 @@ export default {
text-align: center;
color: #000;
font-size: 18px;
margin-top: 100px;
margin-top: 5%;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="nav">
<router-link :to="`/`" ><img src="@/assets/logo.png" class="logoImg"/></router-link>
<router-link :to="`/`"><img src="@/assets/logo.png" class="logoImg"/></router-link>
<el-menu :default-active="activeIndex" router active-text-color="#409EFF" class="oj-navbar" mode="horizontal"
@select="handleSelect">
<el-menu-item index="/">
@ -53,16 +53,28 @@
</el-menu-item>
<div class="account" v-if="JSON.stringify(user) !== '{}'">
<el-dropdown>
<span class="el-dropdown-link">
<el-avatar
:src="user.photo"
/>
&nbsp;&nbsp;{{user.username}}<el-icon class="el-icon--right"><arrow-down /></el-icon>
</span>
<span class="el-dropdown-link">
<el-avatar
:src="user.photo"
/>
&nbsp;&nbsp;{{ user.username }}<el-icon class="el-icon--right"><arrow-down/></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item><router-link to="/user"><el-icon><Avatar /></el-icon></router-link></el-dropdown-item>
<el-dropdown-item @click="logout"><el-icon><CircleClose /></el-icon>退</el-dropdown-item>
<el-dropdown-item>
<router-link to="/user">
<el-icon>
<Avatar/>
</el-icon>
个人中心
</router-link>
</el-dropdown-item>
<el-dropdown-item @click="logout">
<el-icon>
<CircleClose/>
</el-icon>
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@ -74,6 +86,7 @@
<script>
import Cookies from 'js-cookie'
import {ElMessage} from "element-plus";
import router from "@/router";
export default {
@ -94,11 +107,14 @@ export default {
//
check() {
// console.log(JSON.parse(Cookies.get('user'))!==null)
//const user = JSON.parse(Cookies.get('user'))
if (Cookies.get('user')!==undefined && Cookies.get('user')!==null){
this.user = JSON.parse(Cookies.get('user'))
}
console.log(this.user)
// const user = Cookies.get('user')
// this.user = JSON.parse(user)
},
logout(){
logout() {
Cookies.remove('user')
this.$router.go(0);
window.location.reload();
@ -125,11 +141,12 @@ export default {
align-items: center;
font-size: 18px;
}
.el-menu-item:hover{
background-color: white!important;
.el-menu-item:hover {
background-color: white !important;
}
.nav{
.nav {
position: fixed;
top: 0;
z-index: 1000;
@ -139,6 +156,7 @@ export default {
border-bottom: solid 1px #EFF3F5;
padding-left: 5%;
}
.oj-navbar {
width: 85%;
z-index: 999;
@ -149,7 +167,8 @@ export default {
.logo {
width: 130px !important;
}
.logoImg{
.logoImg {
height: 60px;
width: 5%;
float: left;

View File

@ -62,6 +62,8 @@
import {ElMessage} from "element-plus";
import axios from "axios";
import Cookies from 'js-cookie'
import router from "@/router";
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: "Login",
@ -107,9 +109,7 @@ export default {
Cookies.set('user', JSON.stringify(response.data.data),'7d')
//
window.setTimeout(function () {
location.href = "/";
}, 2000);
router.push("/");
} else {
ElMessage({
message: response.data.msg,

View File

@ -1,184 +1,202 @@
<template>
<div class="main">
<NavBar></NavBar>
<el-tabs
v-model="activeName"
@tab-click="handleClick"
class="demo-tabs"
tab-position="left"
:stretch="true"
>
<el-tab-pane label="个人信息">
<el-descriptions
class="margin-top"
:column="1"
size="10px"
border
>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<user/>
</el-icon>
用户名
</div>
</template>
{{ user.username }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Male />
</el-icon>
性别
</div>
</template>
{{user.sex}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<View />
</el-icon>
个人介绍
</div>
</template>
{{user.introduction}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Cellphone />
</el-icon>
电子邮箱
</div>
</template>
{{user.email}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Memo />
</el-icon>
提交次数
</div>
</template>
{{user.submitNum}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<DataAnalysis />
</el-icon>
解题总数
</div>
</template>
{{user.solvedNum}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<office-building/>
</el-icon>
学校
</div>
</template>
{{user.school}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Finished />
</el-icon>
注册时间
</div>
</template>
{{user.registerTime}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Refresh />
</el-icon>
上次登录时间
</div>
</template>
{{user.accessTime}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<PieChart />
</el-icon>
默认使用的语言
</div>
</template>
{{user.language}}
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="修改密码" class="changePass">
<el-form
label-position="top"
label-width="100px"
style="max-width: 460px"
>
<el-form-item label="请输入旧密码">
<el-input type="password" show-password v-model="password.oldpass" />
</el-form-item>
<el-form-item label="请输入新密码">
<el-input type="password" show-password v-model="password.newpass1" />
</el-form-item>
<el-form-item label="确认密码">
<el-input type="password" v-model="password.newpass2" />
</el-form-item>
<el-button type="primary" @click="change">
确认修改
</el-button>
</el-form>
<div style="padding-top:7%;padding-bottom:10%;width:80%;margin-left: 10%;background-color: #FFFFFF;">
<el-tabs
class="demo-tabs"
tab-position="left"
:stretch="true"
v-model="activeName"
@tab-click="handleClick"
>
<el-tab-pane label="个人信息">
<el-descriptions
class="margin-top"
:column="1"
size="10px"
border
>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<user/>
</el-icon>
用户名
</div>
</template>
{{ user.username }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Male />
</el-icon>
性别
</div>
</template>
{{user.sex}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<View />
</el-icon>
个人介绍
</div>
</template>
{{user.introduction}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Cellphone />
</el-icon>
电子邮箱
</div>
</template>
{{user.email}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Memo />
</el-icon>
提交次数
</div>
</template>
{{user.submitNum}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<DataAnalysis />
</el-icon>
解题总数
</div>
</template>
{{user.solvedNum}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<office-building/>
</el-icon>
学校
</div>
</template>
{{user.school}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Finished />
</el-icon>
注册时间
</div>
</template>
{{user.registerTime}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<Refresh />
</el-icon>
上次登录时间
</div>
</template>
{{user.accessTime}}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon class="iconStyle">
<PieChart />
</el-icon>
默认使用的语言
</div>
</template>
{{user.language}}
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="修改密码" class="changePass">
<el-form
label-position="top"
label-width="100px"
style="max-width: 460px"
>
<el-form-item label="请输入旧密码">
<el-input type="password" show-password v-model="password.oldpass" />
</el-form-item>
<el-form-item label="请输入新密码">
<el-input type="password" show-password v-model="password.newpass1" />
</el-form-item>
<el-form-item label="确认密码">
<el-input type="password" v-model="password.newpass2" />
</el-form-item>
<el-button type="primary" @click="change">
确认修改
</el-button>
</el-form>
</el-tab-pane>
<el-tab-pane label="个人资料设置" class="changePass">
<el-form
label-position="top"
label-width="100px"
style="max-width: 460px"
>
<el-form-item label="头像">
<el-upload
class="avatar-uploader"
action="http://localhost:8080/cos/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img w-full v-if="user.photo" :src="user.photo" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="sex">
<el-radio :label="1" size="large"></el-radio>
<el-radio :label="0" size="large"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="简介">
<el-input type="textarea" v-model="user.introduction" />
</el-form-item>
<el-form-item label="学校">
<el-input type="text" v-model="user.school" />
</el-form-item>
<el-form-item label="默认使用语言">
<el-select v-model="user.language" class="m-2" placeholder="Select">
<el-option
v-for="item in languages"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-button type="primary" @click="changeAccount">
确认修改
</el-button>
</el-form>
</el-tab-pane>
</el-tabs>
</div>
</el-tab-pane>
<el-tab-pane label="个人资料设置" class="changePass">
<el-form
label-position="top"
label-width="100px"
style="max-width: 460px"
>
<el-form-item label="用户名">
<el-input type="text" show-password v-model="password.oldpass" />
</el-form-item>
<el-form-item label="简介">
<el-input type="textarea" show-password v-model="password.oldpass" />
</el-form-item>
<el-form-item label="学校">
<el-input type="text" show-password v-model="password.oldpass" />
</el-form-item>
<el-form-item label="默认使用语言">
<el-select v-model="language" class="m-2" placeholder="Select">
<el-option
v-for="item in languages"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-button type="primary" @click="changeAccount">
确认修改
</el-button>
</el-form>
</el-tab-pane>
</el-tabs>
<Footer></Footer>
</div>
</template>
@ -227,7 +245,8 @@ export default {
value: 'JavaScript',
label: 'JavaScript',
},
]
],
sex:"",
};
},
components: {
@ -235,16 +254,60 @@ export default {
Footer
},
methods: {
handleAvatarSuccess( response){
this.user.photo = response.data.url
},
beforeAvatarUpload(rawFile) {
console.log(rawFile.type)
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
ElMessage.error('Avatar picture must be JPG format!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('Avatar picture size can not exceed 2MB!')
return false
}
return true
},
getUser() {
const user = Cookies.get('user')
this.user = JSON.parse(user)
console.log(user)
if (user!==null){
axios.get("/api/user/"+this.user.id).then(response => {
this.user=response.data.data
if (this.user.sex==="男"){
this.sex=1
}else{
this.sex=0
}
})
}
console.log(this.user)
},
changeAccount(){
ElMessage({
message: '修改成功',
type: 'success',
axios.put("/api/user/modify",{
id:this.user.id,
sex:this.sex===1?"男":"女",
introduction:this.user.introduction,
school:this.user.school,
language:this.user.language,
photo:this.user.photo
}).then(response => {
if (response.data.code===200){
ElMessage({
message: '修改成功',
type: 'success',
})
this.getUser()
}else{
ElMessage({
message: response.data.msg,
type: 'error',
})
}
})
},
change(){
if (this.password.oldpass===""){
@ -298,86 +361,30 @@ export default {
</script>
<style scoped>
.main {
background-color: #EFF3F5;
}
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
::v-deep .el-tabs__item {
color: #7E7C77;
height: 60px;
}
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
::v-deep .el-tabs__item.is-active {
color: #15cbf3;
background-color: transparent !important;
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
::v-deep .el-icon-arrow-left {
color: #7E7C77;
}
::v-deep .el-icon-arrow-right {
color: #7E7C77;
}
::v-deep .el-tabs__nav-wrap::after {
height: 0;
}
::v-deep .el-tabs__active-bar {
background-color: #15cbf3;
}
.iconStyle{
margin-right: 10px;
}
.changePass{
padding-top: 50px;
padding-left: 50px;
}
.demo-tabs {
margin-top: 60px;
margin-left: 100px;
margin-right: 100px;
z-index: 999;
height: 490px;
background-color: #FFFFFF;
}
.el-descriptions {
margin-top: 20px;
}
.cell-item {
display: flex;
align-items: center;
}
.margin-top {
margin-top: 20px;
}
.main .el-tabs__item {
padding: 0 !important;
}
.el-tabs__active-bar {
background-color: transparent !important;
}
.demo-tabs > .el-tabs__content {
padding: 32px;
font-size: 32px;
font-weight: 600;
}
.el-tabs--right .el-tabs__content,
.el-tabs--left .el-tabs__content {
height: 100%;
}
.tab {
background-color: red;
width: 100%;
height: 100%;
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
</style>