主要变更: 1. 需求扩展 (20h→28h) - AI自动生成报告初稿 + 人工审核模式 - 12种数据源配置 - 防篡改数字签名机制 2. 页面设计细化 - 左右分栏编辑布局 - 键盘快捷键支持 - 响应式设计断点 3. 专家评审记录 - 技术架构评审意见 - 业务需求评审意见 - 一线民警使用反馈 4. 配置更新 - 添加数据库连接信息 Co-Authored-By: Claude <noreply@anthropic.com>
16 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
XL Prison Management System (XL监狱综合管理平台) - A prison management platform built on the Yudao (芋道) project framework. Currently in active development phase integrating 8 prison-related modules.
Tech Stack
Backend: Java 17, Spring Boot 3.5.9, MyBatis-Plus, Maven multi-module, Spring Security, Swagger/OpenAPI 3 Frontend: Vue 3.5.12, Vite 5.1.4, TypeScript 5.3.3, Element Plus, Pinia, Vue Router, Axios Database: MySQL 8.0+, Redis Build Tools: Maven 3.9+, pnpm 8.6+
Commands
Backend (Java/Maven)
# Build all modules (from backend directory)
cd backend && mvn clean install -DskipTests
# Build specific prison module
cd backend/yudao-module-prison && mvn clean package
# Run development server (from backend directory)
cd backend/yudao-server && mvn spring-boot:run
# Run tests for prison module
cd backend/yudao-module-prison && mvn test
# Run single test class
mvn test -Dtest=GenderEnumTest
Frontend (Vue/Vite)
cd frontend
# Install dependencies
pnpm install
# Dev server (local mode - uses .env.local)
pnpm dev
# Dev server (development mode - uses .env.dev)
pnpm dev-server
# TypeScript type checking
pnpm ts:check
# Build for different environments
pnpm build:local # Local build (uses .env.local)
pnpm build:dev # Development build (uses .env.dev)
pnpm build:test # Testing build (uses .env.test)
pnpm build:prod # Production build (uses .env.prod)
# Linting and formatting
pnpm lint:eslint # ESLint check and fix
pnpm lint:format # Prettier format
pnpm lint:style # Stylelint check and fix
Architecture
Backend Structure
backend/
├── yudao-server/ # Main application entry (Spring Boot)
├── yudao-framework/ # Core framework modules
│ ├── yudao-spring-boot-starter-web
│ ├── yudao-spring-boot-starter-security
│ ├── yudao-spring-boot-starter-mybatis
│ ├── yudao-spring-boot-starter-redis
│ └── ...
├── yudao-module-system/ # User/permission system module
├── yudao-module-infra/ # Infrastructure (code generation, config)
├── yudao-module-prison/ # Prison management module (active development)
└── yudao-module-temp/ # Temporary/template module
Prison Module Structure (yudao-module-prison/):
src/main/java/cn/iocoder/yudao/module/prison/
├── controller/admin/{module}/ # REST API controllers
│ ├── {Module}Controller.java # CRUD endpoints
│ └── vo/ # Request/Response VO objects
│ ├── {Module}SaveReqVO.java # Create/Update request
│ ├── {Module}PageReqVO.java # Page query request
│ ├── {Module}RespVO.java # Response object
│ └── ...
├── service/{module}/ # Service layer
│ ├── {Module}Service.java # Service interface
│ └── impl/
│ └── {Module}ServiceImpl.java # Service implementation
├── dal/ # Data access layer
│ ├── dataobject/{module}/ # MyBatis-Plus DO objects
│ │ └── {Module}DO.java
│ ├── mysql/{module}/ # MyBatis mappers
│ │ └── {Module}Mapper.java
│ └── dal/ # Data access helpers
├── convert/{module}/ # MapStruct converters
│ └── {Module}Convert.java
├── enums/ # Enum definitions
│ └── {Module}Enum.java
└── util/ # Utility classes
Database Schema Convention:
- Table prefix:
prison_{module} - Common fields:
id,creator,create_time,updater,update_time,deleted,tenant_id - Soft delete:
deletedbit(1) field - Tenant support:
tenant_idbigint field
Frontend Structure
frontend/src/
├── views/prison/{module}/ # Page components
│ ├── index.vue # List page with table/search
│ └── {Module}Form.vue # Create/Edit form dialog
├── api/prison/{module}/ # API definitions
│ └── index.ts # Axios API calls + TypeScript types
├── components/ # Shared components
├── store/ # Pinia stores (state management)
├── router/ # Vue Router config
├── hooks/ # Composable hooks
├── types/ # TypeScript type definitions
├── utils/ # Utility functions
└── config/ # Configuration files
Frontend API Pattern (api/prison/{module}/index.ts):
// Interface definitions
export interface Area {
id: number;
name?: string;
code: string;
type: number;
// ...
}
// API object with methods
export const AreaApi = {
getAreaPage: async (params: any) => { ... },
getArea: async (id: number) => { ... },
createArea: async (data: Area) => { ... },
updateArea: async (data: Area) => { ... },
deleteArea: async (id: number) => { ... },
deleteAreaList: async (ids: number[]) => { ... },
exportArea: async (params) => { ... }
}
Frontend View Pattern (views/prison/{module}/index.vue):
- Uses Element Plus table with pagination
- Search form with filters
- CRUD operations with dialog forms
- Export functionality
- Batch delete support
Data Flow Pattern
Frontend (Vue Component)
↓
API Layer (TypeScript + Axios)
↓
Backend Controller (REST API)
↓
Service Layer (Business Logic)
↓
Data Access (MyBatis-Plus)
↓
MySQL Database
Current Integration Status
8 Modules integrated into prison module:
| Module | Chinese | Backend Path | Frontend Path | Status |
|---|---|---|---|---|
| Area | 监区管理 | controller/admin/area/ |
views/prison/area/ |
✅ Complete |
| Cell | 监室管理 | controller/admin/cell/ |
views/prison/cell/ |
✅ Complete |
| Consumption | 消费记录 | controller/admin/consumption/ |
views/prison/consumption/ |
✅ Complete |
| Question | 问卷问题 | controller/admin/question/ |
views/prison/question/ |
✅ Complete |
| Questionnaire | 问卷模板 | controller/admin/questionnaire/ |
views/prison/questionnaire/ |
✅ Complete |
| QuestionnaireRecord | 问卷答题记录 | controller/admin/questionnairerecord/ |
views/prison/questionnairerecord/ |
✅ Complete |
| RiskAssessment | 危险评估 | controller/admin/riskassessment/ |
views/prison/riskassessment/ |
✅ Complete |
| Score | 计分考核 | controller/admin/score/ |
views/prison/score/ |
✅ Complete |
Core Features per Module:
- ✅ RESTful CRUD API endpoints
- ✅ MyBatis-Plus data access layer
- ✅ Request/Response VO objects
- ✅ MapStruct type conversion
- ✅ Frontend list page with pagination
- ✅ Frontend form dialogs for create/edit
- ✅ Export to Excel functionality
- ✅ Batch delete operations
- ✅ Menu permissions SQL scripts
Recent Updates (2026-01-15):
- Code review completed for questionnaire modules (Question, Questionnaire, QuestionnaireRecord)
- Backend fixes: VO field synchronization, batch update optimization, empty validation
- Frontend fixes: TypeScript type definitions, date formatting standardization
- Added enum classes: QuestionnaireStatusEnum, QuestionnaireRecordStatusEnum, QuestionnaireRecordPassStatusEnum
- Added database migration scripts for new columns
Database Configuration
修改表结构的是直接采用 mysql 命令进行操帮我操作
Development Database:
URL: jdbc:mysql://192.168.10.130:3306/xlcp_dev?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
Username: xlcp_dev
Password: xlcp_dev
SQL Scripts Location:
- Module tables and permissions:
backend/yudao-module-prison/src/main/resources/sql/prison_module.sql - Execute this script to create all prison module tables and menu permissions
Configuration Files
Backend Configuration
Location: backend/yudao-server/src/main/resources/
Key Files:
application.yaml- Base configurationapplication-local.yaml- Local development (port 48080)application-dev.yaml- Development environment
Mock Settings (application-local.yaml):
yudao:
security:
mock-enable: true # 是否开启 Token 的模拟机制(生产环境必须关闭)
mock-secret: emsoft # Token 模拟机制的 Token 前缀
使用场景:方便使用 Postman、Swagger 调试接口时模拟 Token 认证,无需真实登录。
多租户调用方式:
# 格式:Authorization: Bearer {mockSecret}{用户ID}
# 必须传递 tenant-id 请求头
curl -X GET "{{url}}" \
-H "Authorization: Bearer emsoft1" \
-H "tenant-id: 1"
说明:
| 参数 | 说明 | 示例值 |
|---|---|---|
Authorization |
mock token,格式 {mockSecret}{userId} |
Bearer emsoft1 表示用户 ID 为 1 |
tenant-id |
租户 ID(多租户场景必传) | 1 |
示例:
- 模拟用户 ID=1,租户 ID=1:
Authorization: Bearer emsoft1+tenant-id: 1 - 模拟用户 ID=2,租户 ID=1:
Authorization: Bearer emsoft2+tenant-id: 1
Frontend Configuration
Location: frontend/
Key Files:
.env.local- Local development environment.env.dev- Development environment.env.test- Testing environment.env.prod- Production environment
Local Environment (.env.local):
VITE_BASE_URL='http://localhost:48080'
VITE_API_URL='/admin-api'
VITE_DEV=true
Development Workflow
Adding a New Module
-
Backend:
- Create package:
controller/admin/{module}/,service/{module}/,dal/dataobject/{module}/, etc. - Define DO in
dal/dataobject/{module}/{Module}DO.java - Create Mapper in
dal/mysql/{module}/{Module}Mapper.java - Implement Service in
service/{module}/impl/{Module}ServiceImpl.java - Create Controller in
controller/admin/{module}/{Module}Controller.java - Define VOs in
controller/admin/{module}/vo/ - Add MapStruct converter in
convert/{module}/{Module}Convert.java - Add enum if needed in
enums/
- Create package:
-
Frontend:
- Create API:
api/prison/{module}/index.ts - Create views:
views/prison/{module}/index.vueand{Module}Form.vue - Define TypeScript interfaces
- Implement CRUD operations
- Create API:
-
Database:
- Add table creation SQL to
backend/yudao-module-prison/src/main/resources/sql/prison_module.sql - Add menu permission SQL
- Add table creation SQL to
Testing a Module
Backend:
# Test all prison module
cd backend/yudao-module-prison && mvn test
# Test specific class
mvn test -Dtest=PrisonAreaControllerTest
Frontend:
# Type check only
cd frontend && pnpm ts:check
# Dev server with hot reload
pnpm dev
Common Patterns
Backend Controller Pattern
@RestController
@RequestMapping("/prison/{module}")
@Tag(name = "管理后台 - {中文名称}")
public class {Module}Controller {
@Resource
private {Module}Service {module}Service;
@PostMapping("/create")
@Operation(summary = "创建{中文名称}")
@PreAuthorize("@ss.hasPermission('prison:{module}:create')")
public CommonResult<Long> create(@Valid @RequestBody {Module}SaveReqVO vo) {
return success({module}Service.create(vo));
}
@PutMapping("/update")
@Operation(summary = "更新{中文名称}")
@PreAuthorize("@ss.hasPermission('prison:{module}:update')")
public CommonResult<Boolean> update(@Valid @RequestBody {Module}SaveReqVO vo) {
return success({module}Service.update(vo));
}
@DeleteMapping("/delete")
@Operation(summary = "删除{中文名称}")
@PreAuthorize("@ss.hasPermission('prison:{module}:delete')")
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
return success({module}Service.delete(id));
}
@GetMapping("/page")
@Operation(summary = "分页查询{中文名称}")
@PreAuthorize("@ss.hasPermission('prison:{module}:query')")
public CommonResult<PageResult<{Module}RespVO>> page(@Valid {Module}PageReqVO vo) {
return success({module}Service.page(vo));
}
@GetMapping("/get")
@Operation(summary = "查询{中文名称}详情")
@PreAuthorize("@ss.hasPermission('prison:{module}:query')")
public CommonResult<{Module}RespVO> get(@RequestParam("id") Long id) {
return success({module}Service.get(id));
}
@GetMapping("/export-excel")
@Operation(summary = "导出{中文名称} Excel")
@PreAuthorize("@ss.hasPermission('prison:{module}:export')")
public void exportExcel(@Valid {Module}PageReqVO vo, HttpServletResponse response) {
{module}Service.exportExcel(vo, response);
}
}
Service Layer Pattern
public interface {Module}Service {
Long create({Module}SaveReqVO vo);
Boolean update({Module}SaveReqVO vo);
Boolean delete(Long id);
{Module}RespVO get(Long id);
PageResult<{Module}RespVO> page({Module}PageReqVO vo);
void exportExcel({Module}PageReqVO vo, HttpServletResponse response);
}
Frontend API Pattern
export interface {Module} {
id: number;
// ... other fields
}
export const {Module}Api = {
getPage: async (params: any) => {
return await request.get({ url: `/{module}/page`, params })
},
get: async (id: number) => {
return await request.get({ url: `/{module}/get?id=${id}` })
},
create: async (data: {Module}) => {
return await request.post({ url: `/{module}/create`, data })
},
update: async (data: {Module}) => {
return await request.put({ url: `/{module}/update`, data })
},
delete: async (id: number) => {
return await request.delete({ url: `/{module}/delete?id=${id}` })
},
deleteList: async (ids: number[]) => {
return await request.delete({ url: `/{module}/delete-list?ids=${ids.join(',')}` })
},
export: async (params) => {
return await request.download({ url: `/{module}/export-excel`, params })
}
}
Important Notes
- Package Prefix: All prison module classes use
cn.iocoder.yudao.module.prison - API Base Path:
/admin-api/prison/{module} - Permission Codes: Follow pattern
prison:{module}:{action}(e.g.,prison:area:create) - Frontend Paths: Use
views/prison/andapi/prison/directories - Database Tables: Use
prison_prefix and soft delete (deletedfield) - Error Codes: Defined in
ErrorCodeConstants.java(shared across modules) - Enum Types: Defined in
enums/directory withEnumsuffix - VO Naming:
SaveReqVO,PageReqVO,RespVOsuffixes - DO Naming:
{Module}DOwith table mapping via@TableName - Mapper Naming:
{Module}MapperextendingBaseMapper<{Module}DO> - Service Impl: Located in
service/{module}/impl/directory
Code Generation
Source: codegen/ directory contains template files for generating new modules
Usage: Copy and adapt these templates when adding new prison modules
Build & Deployment
Backend JAR: backend/yudao-server/target/yudao-server-{version}.jar
Frontend Dist: frontend/dist/ (static files for nginx)
Troubleshooting
Common Issues:
- Maven dependency issues: Run
mvn clean install -Uto force update - Frontend type errors: Run
pnpm ts:checkto identify issues - Database connection: Verify MySQL is running and credentials in
application-local.yaml - Mock mode: Check
yudao.mock.enablesetting in configuration - Port conflicts: Default backend port is 48080
Debug Mode:
- Backend: Add
--debugto mvn command for remote debugging on port 5005 - Frontend: Browser dev tools + Vue DevTools browser extension