1、工作日志增加类型, 类型: 1 工作计划 2 工作日志 3 个人日志 9 其他;
2、日历上有日志记录的日期,原来点击日期是显示当天的工作日志,现在调整为 日志列表,点击后,在弹窗内显示日志详情,同时增加返回列表的功能。
3、同一天,针对(工作计划和工作日志)类型的日志,只允许创建一个
4、管理后台调整: 在首页,点击“添加日志”,要在首页弹出“添加日志”,而不是在“工作日志”的页面弹出弹窗
5、管理后台调整: 在“添加日志“和”编辑日志“的内容时,能够同步以markdown方式展示编辑的内容
352 lines
10 KiB
Markdown
352 lines
10 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Work Log Service Platform (工作日志服务平台) - A lightweight, multi-terminal work log management system with PC admin console and mobile H5 interface.
|
|
|
|
**Current Version**: V1.1 (2026-02-26)
|
|
|
|
**Architecture**: Monolithic application with frontend-backend separation
|
|
- **Backend**: worklog-api (Spring Boot 3.2.2 + MyBatis-Plus 3.5.5)
|
|
- **Management Console**: worklog-web (Vue 3 + Element Plus)
|
|
- **Mobile**: worklog-mobile (Vue 3 + Vant 4)
|
|
|
|
## Development Environment
|
|
|
|
### Prerequisites
|
|
- **JDK**: 21 (LTS)
|
|
- **Maven**: 3.6+
|
|
- **Node.js**: 18+ (for frontend)
|
|
- **MySQL**: 8.0
|
|
- **Redis**: 7.x
|
|
|
|
### Environment Configuration
|
|
- **Database**: localhost:3306/worklog (user: worklog, password: Wlog@123)
|
|
- **Redis**: localhost:6379 (password: zjf@123456)
|
|
- **Backend Port**: 8080
|
|
- **Frontend Dev Servers**: worklog-web (5173), worklog-mobile (5174)
|
|
|
|
## Common Development Commands
|
|
|
|
### Backend (worklog-api/)
|
|
|
|
```bash
|
|
# Compile
|
|
mvn clean compile
|
|
|
|
# Run tests (35/36 pass, 1 skipped due to MyBatis Plus mock limitation)
|
|
mvn test
|
|
|
|
# Run single test
|
|
mvn test -Dtest=LogServiceTest
|
|
|
|
# Run single test method
|
|
mvn test -Dtest=LogServiceTest#createLog_success_defaultType
|
|
|
|
# Package
|
|
mvn clean package
|
|
|
|
# Run application
|
|
mvn spring-boot:run
|
|
|
|
# Or run packaged JAR
|
|
java -jar target/worklog-api-1.0.0.jar
|
|
```
|
|
|
|
**Key URLs**:
|
|
- Health check: http://localhost:8080/api/v1/health
|
|
- API documentation: http://localhost:8080/swagger-ui.html
|
|
|
|
### Frontend (worklog-web/ and worklog-mobile/)
|
|
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Development server
|
|
npm run dev
|
|
|
|
# Build for production
|
|
npm run build
|
|
|
|
# Type check
|
|
npm run type-check
|
|
|
|
# Lint
|
|
npm run lint
|
|
```
|
|
|
|
### Database Setup
|
|
|
|
```bash
|
|
# From project root
|
|
cd /home/along/MyCode/wanjiabuluo/worklog
|
|
|
|
# Initialize database (creates worklog database and tables)
|
|
mysql -u worklog -p < sql/init_database.sql
|
|
# Password: Wlog@123
|
|
|
|
# Apply V1.1 migration (adds log_type field)
|
|
mysql -u worklog -p worklog < sql/v1.1_add_log_type.sql
|
|
```
|
|
|
|
## Architecture Overview
|
|
|
|
### Backend Layered Architecture
|
|
|
|
**Critical**: Follow the strict layering pattern:
|
|
|
|
```
|
|
Controller → Service → DataService → Mapper → Database
|
|
```
|
|
|
|
**Layer Responsibilities**:
|
|
1. **Controller**: Request handling, parameter validation, calls Service
|
|
2. **Service**: Business logic, transaction control, DTO/VO conversion
|
|
3. **DataService**: Data access encapsulation, CRUD operations
|
|
4. **Mapper**: MyBatis database operations
|
|
|
|
**Important Conventions**:
|
|
- **Never inject Mapper directly into Service** - always use DataService as intermediary
|
|
- **DataService naming**: `XxxDataService` / `XxxDataServiceImpl` (not `XxxService`)
|
|
- **All MyBatis-Plus files go in `data/` directory**: entity/, mapper/, service/
|
|
- **Primary Keys**: VARCHAR(20) storing 19-digit snowflake IDs
|
|
- **Audit Fields**: All entities have created_by, created_time, updated_by, updated_time, deleted
|
|
- **Logical Deletion**: Use `deleted` field (0=active, 1=deleted), never physical delete
|
|
|
|
### Directory Structure Principle
|
|
|
|
```
|
|
worklog-api/src/main/java/com/wjbl/worklog/
|
|
├── controller/ # REST API endpoints
|
|
├── service/ # Business logic layer
|
|
│ └── impl/
|
|
├── data/ # Data access layer (MyBatis-Plus)
|
|
│ ├── entity/ # Database entities
|
|
│ ├── mapper/ # MyBatis Mapper interfaces
|
|
│ └── service/ # DataService layer
|
|
│ └── impl/
|
|
├── dto/ # Data Transfer Objects (API input)
|
|
├── vo/ # View Objects (API output)
|
|
├── enums/ # Enumerations
|
|
└── common/ # Common utilities
|
|
├── Result.java # Unified API response wrapper
|
|
├── context/ # UserContext for current user info
|
|
└── exception/ # Exception handling
|
|
```
|
|
|
|
### API Design Standards
|
|
|
|
**RESTful URL Pattern**: `/api/v1/{resource}/{action}`
|
|
|
|
**Unified Response Format**:
|
|
```json
|
|
{
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": {},
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
**Authentication**:
|
|
- Token in header: `Authorization: Bearer {token}`
|
|
- Token stored in Redis: `auth:token:{token}` (TTL: 24h)
|
|
- UserContext provides current user: `UserContext.getUserId()`, `UserContext.getRole()`
|
|
|
|
### Frontend Architecture
|
|
|
|
**State Management**:
|
|
- Pinia stores for user/auth state
|
|
- No Vuex
|
|
|
|
**API Management**:
|
|
- All API calls in `src/api/` directory
|
|
- Never hardcode URLs in components
|
|
- Use axios request wrapper with token injection
|
|
|
|
**UI Frameworks**:
|
|
- **worklog-web**: Element Plus (desktop admin console)
|
|
- **worklog-mobile**: Vant 4 (mobile H5)
|
|
|
|
## Key Business Logic
|
|
|
|
### Log Type System (V1.1)
|
|
|
|
**4 Log Types**:
|
|
1. `1` - Work Plan (工作计划)
|
|
2. `2` - Work Log (工作日志) - **DEFAULT**
|
|
3. `3` - Personal Log (个人日志)
|
|
4. `9` - Other (其他)
|
|
|
|
**Uniqueness Constraint**:
|
|
- Work Plan and Work Log: **ONE per user per day**
|
|
- Personal Log and Other: **UNLIMITED** per day
|
|
|
|
**Implementation**:
|
|
- `LogTypeEnum.requiresUnique()` determines if uniqueness check needed
|
|
- `workLogDataService.getByUserIdLogDateAndType()` checks existing logs
|
|
- Composite index: `idx_user_date_type (user_id, log_date, log_type)`
|
|
|
|
### Calendar Interaction Pattern
|
|
|
|
**Breaking API Change in V1.1**:
|
|
- **Old**: `GET /api/v1/log/by-date` returned single `LogVO`
|
|
- **New**: `GET /api/v1/log/by-date` returns `List<LogVO>` (sorted by log type)
|
|
|
|
**Frontend Patterns**:
|
|
- **Management Console**: Dual-dialog pattern (list dialog → detail dialog with back button)
|
|
- **Mobile**: Multi-mode pattern (list mode ↔ detail mode ↔ create mode in single popup)
|
|
|
|
### Permission System
|
|
|
|
**2 Roles**:
|
|
- `USER`: View/edit own logs and profile
|
|
- `ADMIN`: All permissions + user management + template management + view all logs
|
|
|
|
**Permission Checks**:
|
|
```java
|
|
// In Service layer
|
|
String currentUserId = UserContext.getUserId();
|
|
String currentRole = UserContext.getRole();
|
|
|
|
if (!workLog.getUserId().equals(currentUserId) && !"ADMIN".equals(currentRole)) {
|
|
throw new BusinessException("无权操作他人日志");
|
|
}
|
|
```
|
|
|
|
## Testing Guidelines
|
|
|
|
### Backend Unit Tests
|
|
|
|
**Location**: `worklog-api/src/test/java/`
|
|
|
|
**Key Patterns**:
|
|
```java
|
|
@ExtendWith(MockitoExtension.class)
|
|
class ServiceTest {
|
|
@Mock
|
|
private XxxDataService dataService;
|
|
|
|
@InjectMocks
|
|
private XxxServiceImpl service;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
// Use lenient() for flexible mocking to avoid UnnecessaryStubbing errors
|
|
lenient().when(dataService.method()).thenReturn(value);
|
|
|
|
// Set UserContext for permission tests
|
|
UserContext.setUserInfo(new UserInfo("user-id", "username", "name", "USER"));
|
|
}
|
|
}
|
|
```
|
|
|
|
**Known Limitation**:
|
|
- 1 test disabled in `LogServiceTest.deleteLog_success` due to MyBatis Plus Lambda cache not working in mock environment
|
|
- Permission logic validated in other tests
|
|
|
|
### Frontend Testing
|
|
|
|
Currently no automated frontend tests. Manual testing via browser.
|
|
|
|
## Logging and Tracing
|
|
|
|
**Log Files** (in `logs/` directory):
|
|
- `app.log` - Main application log
|
|
- `sql.log` - SQL execution log (mandatory separate file)
|
|
|
|
**Log Format** (includes trace IDs):
|
|
```
|
|
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId:-}][%X{spanId:-}] %-5level %logger{50} - %msg%n
|
|
```
|
|
|
|
**TraceId/SpanId**:
|
|
- Automatically added by `TraceInterceptor`
|
|
- Propagated via HTTP headers: `X-Trace-Id`, `X-Span-Id`
|
|
|
|
## Configuration Management
|
|
|
|
**Development**:
|
|
- Configuration in `src/main/resources/application.yml`
|
|
- Use `application-dev.yml` for dev-specific overrides
|
|
|
|
**Production** (follows architecture design standard):
|
|
- `conf/env.properties` - Unified environment config (DB, Redis, Nacos)
|
|
- `conf/service.properties` - Service-specific config
|
|
- Loaded by `bin/start.sh` script
|
|
|
|
**Security**:
|
|
- Never commit actual config files with credentials
|
|
- Use `.example` templates in repository
|
|
- All passwords encrypted with BCrypt (strength 10)
|
|
|
|
## Database Conventions
|
|
|
|
**Naming**:
|
|
- Tables: snake_case (e.g., `work_log`, `sys_user`)
|
|
- Fields: snake_case (e.g., `log_date`, `user_id`)
|
|
- Java entities: camelCase with MyBatis-Plus mapping
|
|
|
|
**Standard Audit Fields**:
|
|
```sql
|
|
created_by VARCHAR(20) NOT NULL,
|
|
created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_by VARCHAR(20) NOT NULL,
|
|
updated_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
deleted TINYINT(1) NOT NULL DEFAULT 0
|
|
```
|
|
|
|
**Indexes**:
|
|
- Always index foreign keys
|
|
- Add composite indexes for common query patterns
|
|
- Example: `idx_user_date_type (user_id, log_date, log_type)` for uniqueness checks
|
|
|
|
## Common Pitfalls
|
|
|
|
1. **Don't inject Mapper into Service** - Always use DataService layer
|
|
2. **Don't skip UserContext.setUserInfo() in tests** - Required for permission checks
|
|
3. **Don't use `when()` for unused stubs** - Use `lenient().when()` to avoid strict stubbing errors
|
|
4. **Don't use List.of() in tests** - It returns immutable list; use `ArrayList` instead
|
|
5. **Don't modify log_type and log_date in updates** - These fields are immutable after creation
|
|
6. **Remember breaking API change** - `/by-date` endpoint returns List, not single object
|
|
7. **Don't forget default values** - `logType` defaults to 2 (Work Log) if not specified
|
|
8. **Check requiresUnique()** - Work Plan/Work Log need uniqueness validation; Personal/Other don't
|
|
|
|
## Documentation
|
|
|
|
**Key Documents** (in `doc/` directory):
|
|
- `产品需求文档PRD.md` - Product requirements (V1.1)
|
|
- `架构设计文档.md` - Architecture design
|
|
- `后端模块详细设计文档.md` - Backend detailed design
|
|
- `前端详细设计文档.md` - Frontend detailed design
|
|
- `CHANGELOG.md` - Version history and changes
|
|
|
|
**Database**:
|
|
- `sql/init_database.sql` - Database initialization
|
|
- `sql/v1.1_add_log_type.sql` - V1.1 migration script
|
|
|
|
## Default Accounts
|
|
|
|
**Admin**:
|
|
- Username: `admin`
|
|
- Password: `admin123` (BCrypt hashed in database)
|
|
- ID: `1000000000000000001`
|
|
|
|
## Version Information
|
|
|
|
**V1.1** (2026-02-26):
|
|
- Added log type classification (4 types)
|
|
- Unique constraint for work plan/log types
|
|
- Calendar list view with multiple logs per day
|
|
- API breaking change: `/by-date` returns array
|
|
- 15 new unit tests (97.2% pass rate: 35/36)
|
|
|
|
**V1.0** (Initial):
|
|
- Basic work log management
|
|
- User management
|
|
- Template management
|
|
- PC and mobile support
|