Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
1、执行任务的时候,首先分析任务,然后将该任务分成多个可执行的小任务,一步一步执行。
|
||||
2、不要启动我项目的服务
|
||||
3、若是新建项目或者开发新的功能,首先使用context7 MCP服务来寻找对应的文档
|
||||
4、若是修改业务逻辑等,就不要使用context7 MCP服务来寻找对应的文档,先查看查看前端该功能对应的后端接口,查看后端接口的逻辑,若是已经实现就返回前端处理逻辑,若是后端还们没有实现,则先处理后端在处理前端。
|
||||
5、若是apply_diff失败或者文件修改编辑失败,就要先保存该文件然后重新读取在做修改再来apply_diff
|
||||
6、使用filesystem MCP服务
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"sequentialthinking": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-sequential-thinking"
|
||||
],
|
||||
"alwaysAllow": [
|
||||
"sequentialthinking"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
100
README.md
Normal file
100
README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# 笔记应用 (Biji App)
|
||||
|
||||
这是一个功能完善的全栈笔记应用程序,采用前后端分离架构。前端使用 Vue 3 构建,后端使用 Spring Boot 3 实现。
|
||||
|
||||
## ✨ 功能特性 (Features)
|
||||
|
||||
* **用户认证**: 支持用户注册、登录和 JWT (JSON Web Token) 认证。
|
||||
* **Markdown 笔记**: 提供功能强大的 Markdown 编辑器,支持实时预览和丰富的格式化选项。
|
||||
* **图片管理**: 支持在笔记中上传、插入和管理图片。
|
||||
* **笔记组织**: 用户可以创建分组 (Categories/Groups) 来管理和组织笔记。
|
||||
* **回收站**: 提供回收站功能,可以恢复被误删除的笔记或分组。
|
||||
* **系统设置**: 提供基本的系统配置功能。
|
||||
|
||||
## 🛠️ 技术栈 (Tech Stack)
|
||||
|
||||
### 后端 (Backend - `biji-houdaun`)
|
||||
|
||||
* **框架 (Framework)**: Spring Boot 3.5.0
|
||||
* **语言 (Language)**: Java 17
|
||||
* **数据访问 (Data Access)**: MyBatis-Plus 3.5.7
|
||||
* **数据库 (Database)**: SQLite
|
||||
* **API 文档 (API Docs)**: Knife4j / SpringDoc
|
||||
* **安全 (Security)**: Spring Security, JJWT
|
||||
* **工具库 (Utilities)**: Lombok, Hutool, Commons Codec
|
||||
|
||||
### 前端 (Frontend - `biji-qianduan`)
|
||||
|
||||
* **框架 (Framework)**: Vue 3
|
||||
* **构建工具 (Build Tool)**: Vite
|
||||
* **UI 库 (UI Library)**: Element Plus
|
||||
* **状态管理 (State Management)**: Pinia
|
||||
* **路由 (Routing)**: Vue Router
|
||||
* **Markdown 编辑器**: Vditor / @kangc/v-md-editor
|
||||
* **HTTP 客户端 (HTTP Client)**: Axios (封装在 `src/utils/axios.js` 中)
|
||||
|
||||
## 📂 项目结构 (Project Structure)
|
||||
|
||||
```
|
||||
.
|
||||
├── biji-houdaun/ # 后端 Spring Boot 项目
|
||||
│ ├── src/main/java/ # Java 源码
|
||||
│ │ └── com/test/bijihoudaun/
|
||||
│ │ ├── controller/ # API 控制器
|
||||
│ │ ├── service/ # 业务逻辑服务
|
||||
│ │ ├── mapper/ # MyBatis 数据映射
|
||||
│ │ ├── entity/ # 数据库实体
|
||||
│ │ ├── config/ # 应用配置
|
||||
│ │ └── common/ # 通用工具 (异常处理、响应)
|
||||
│ └── pom.xml # Maven 依赖配置
|
||||
│
|
||||
├── biji-qianduan/ # 前端 Vue 项目
|
||||
│ ├── src/ # 前端源码
|
||||
│ │ ├── api/ # API 请求模块
|
||||
│ │ ├── assets/ # 静态资源 (CSS, images)
|
||||
│ │ ├── components/ # Vue 组件
|
||||
│ │ ├── router/ # 路由配置
|
||||
│ │ ├── stores/ # Pinia 状态管理
|
||||
│ │ └── utils/ # 工具函数
|
||||
│ └── package.json # NPM 依赖配置
|
||||
│
|
||||
├── sql/ # 数据库初始化脚本
|
||||
├── uploads/ # 用户上传文件目录
|
||||
├── doc/ # 项目相关文档
|
||||
└── README.md # 本文档
|
||||
```
|
||||
|
||||
## 🚀 快速开始 (Getting Started)
|
||||
|
||||
### 环境要求
|
||||
|
||||
* JDK 17
|
||||
* Maven 3.x
|
||||
* Node.js 18+
|
||||
* pnpm (或 npm/yarn)
|
||||
|
||||
### 后端启动
|
||||
|
||||
1. **克隆项目**: `git clone <repository-url>`
|
||||
2. **数据库初始化**: 使用 `sql/` 目录下的脚本初始化 SQLite 数据库 (`mydatabase.db`)。
|
||||
3. **配置**: 检查 `biji-houdaun/src/main/resources/application-dev.yml` 中的配置是否正确。
|
||||
4. **运行**: 在 `biji-houdaun` 目录下,通过 IDE 直接运行 `BijiHoudaunApplication.java` 或使用 Maven:
|
||||
```bash
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
### 前端启动
|
||||
|
||||
1. **进入目录**: `cd biji-qianduan`
|
||||
2. **安装依赖**:
|
||||
```bash
|
||||
pnpm install
|
||||
# 或者使用 npm / yarn
|
||||
# npm install
|
||||
# yarn install
|
||||
```
|
||||
3. **运行开发服务器**:
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
4. **访问应用**: 在浏览器中打开 `http://localhost:5173` (或其他 Vite 指定的端口)。
|
||||
@@ -45,11 +45,14 @@ public class SecurityConfig {
|
||||
@Value("${jwt.tokenHead}")
|
||||
private String tokenHead;
|
||||
|
||||
|
||||
// 配置了密码编码器
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
// 配置了安全过滤器链
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter = new JwtAuthenticationTokenFilter(userDetailsService, jwtTokenUtil, tokenHeader, tokenHead);
|
||||
@@ -69,7 +72,7 @@ public class SecurityConfig {
|
||||
};
|
||||
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.csrf(csrf -> csrf.disable()) // 配置了 CSRF 禁用、无状态会话管理
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(authz -> authz
|
||||
// 1. 动态允许公共端点
|
||||
|
||||
@@ -37,7 +37,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
throw new UsernameNotFoundException("User not found with username: " + username);
|
||||
}
|
||||
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
|
||||
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>()); // 账号,密码,权限
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
package com.test.bijihoudaun.util;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.ZoneId;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 时间工具类
|
||||
* 提供常用的时间操作方法
|
||||
*
|
||||
* @author CodeGeeX
|
||||
* @since 2024
|
||||
*/
|
||||
public class DateTimeUtil {
|
||||
|
||||
// 常用的时间格式
|
||||
public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
|
||||
public static final String COMPACT_DATETIME_FORMAT = "yyyyMMddHHmmss";
|
||||
public static final String COMPACT_DATE_FORMAT = "yyyyMMdd";
|
||||
|
||||
/**
|
||||
* 获取当前时间(LocalDateTime)
|
||||
*
|
||||
* @return 当前时间
|
||||
*/
|
||||
public static LocalDateTime getCurrentDateTime() {
|
||||
return LocalDateTime.now();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期(LocalDate)
|
||||
*
|
||||
* @return 当前日期
|
||||
*/
|
||||
public static LocalDate getCurrentDate() {
|
||||
return LocalDate.now();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间戳(毫秒)
|
||||
*
|
||||
* @return 当前时间戳
|
||||
*/
|
||||
public static long getCurrentTimestamp() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间戳(秒)
|
||||
*
|
||||
* @return 当前时间戳(秒)
|
||||
*/
|
||||
public static long getCurrentTimestampSeconds() {
|
||||
return System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转LocalDateTime
|
||||
* 使用默认格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @param dateTimeStr 时间字符串
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime stringToDateTime(String dateTimeStr) {
|
||||
return stringToDateTime(dateTimeStr, DEFAULT_DATETIME_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转LocalDateTime
|
||||
*
|
||||
* @param dateTimeStr 时间字符串
|
||||
* @param pattern 时间格式
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime stringToDateTime(String dateTimeStr, String pattern) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return LocalDateTime.parse(dateTimeStr, formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转LocalDate
|
||||
* 使用默认格式:yyyy-MM-dd
|
||||
*
|
||||
* @param dateStr 日期字符串
|
||||
* @return LocalDate对象
|
||||
*/
|
||||
public static LocalDate stringToDate(String dateStr) {
|
||||
return stringToDate(dateStr, DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转LocalDate
|
||||
*
|
||||
* @param dateStr 日期字符串
|
||||
* @param pattern 日期格式
|
||||
* @return LocalDate对象
|
||||
*/
|
||||
public static LocalDate stringToDate(String dateStr, String pattern) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return LocalDate.parse(dateStr, formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime转字符串
|
||||
* 使用默认格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @param dateTime LocalDateTime对象
|
||||
* @return 时间字符串
|
||||
*/
|
||||
public static String dateTimeToString(LocalDateTime dateTime) {
|
||||
return dateTimeToString(dateTime, DEFAULT_DATETIME_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime转字符串
|
||||
*
|
||||
* @param dateTime LocalDateTime对象
|
||||
* @param pattern 时间格式
|
||||
* @return 时间字符串
|
||||
*/
|
||||
public static String dateTimeToString(LocalDateTime dateTime, String pattern) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return dateTime.format(formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDate转字符串
|
||||
* 使用默认格式:yyyy-MM-dd
|
||||
*
|
||||
* @param date LocalDate对象
|
||||
* @return 日期字符串
|
||||
*/
|
||||
public static String dateToString(LocalDate date) {
|
||||
return dateToString(date, DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDate转字符串
|
||||
*
|
||||
* @param date LocalDate对象
|
||||
* @param pattern 日期格式
|
||||
* @return 日期字符串
|
||||
*/
|
||||
public static String dateToString(LocalDate date, String pattern) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
return date.format(formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间戳转LocalDateTime
|
||||
*
|
||||
* @param timestamp 时间戳(毫秒)
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime timestampToDateTime(long timestamp) {
|
||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime转时间戳
|
||||
*
|
||||
* @param dateTime LocalDateTime对象
|
||||
* @return 时间戳(毫秒)
|
||||
*/
|
||||
public static long dateTimeToTimestamp(LocalDateTime dateTime) {
|
||||
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
/**
|
||||
* Date转LocalDateTime
|
||||
*
|
||||
* @param date Date对象
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime dateToDateTime(Date date) {
|
||||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime转Date
|
||||
*
|
||||
* @param dateTime LocalDateTime对象
|
||||
* @return Date对象
|
||||
*/
|
||||
public static Date dateTimeToDate(LocalDateTime dateTime) {
|
||||
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间的字符串表示
|
||||
* 使用默认格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @return 当前时间字符串
|
||||
*/
|
||||
public static String getCurrentDateTimeString() {
|
||||
return dateTimeToString(getCurrentDateTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间的字符串表示
|
||||
*
|
||||
* @param pattern 时间格式
|
||||
* @return 当前时间字符串
|
||||
*/
|
||||
public static String getCurrentDateTimeString(String pattern) {
|
||||
return dateTimeToString(getCurrentDateTime(), pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期的字符串表示
|
||||
* 使用默认格式:yyyy-MM-dd
|
||||
*
|
||||
* @return 当前日期字符串
|
||||
*/
|
||||
public static String getCurrentDateString() {
|
||||
return dateToString(getCurrentDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期的字符串表示
|
||||
*
|
||||
* @param pattern 日期格式
|
||||
* @return 当前日期字符串
|
||||
*/
|
||||
public static String getCurrentDateString(String pattern) {
|
||||
return dateToString(getCurrentDate(), pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查字符串是否为有效的日期时间格式
|
||||
*
|
||||
* @param dateTimeStr 日期时间字符串
|
||||
* @param pattern 格式模式
|
||||
* @return 是否有效
|
||||
*/
|
||||
public static boolean isValidDateTime(String dateTimeStr, String pattern) {
|
||||
try {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
LocalDateTime.parse(dateTimeStr, formatter);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查字符串是否为有效的日期格式
|
||||
*
|
||||
* @param dateStr 日期字符串
|
||||
* @param pattern 格式模式
|
||||
* @return 是否有效
|
||||
*/
|
||||
public static boolean isValidDate(String dateStr, String pattern) {
|
||||
try {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
LocalDate.parse(dateStr, formatter);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user