diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3e596ed --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,216 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## 项目概述 + +**数字支行辅助管理系统(IBS)** - 基于 若依框架 v3.8.8 的前后端分离全栈项目,专注于银行支行的网格化营销、客户管理和走访业务。 + +## 常用命令 + +### 后端开发 + +```bash +# Maven 打包(跳过测试) +mvn clean package -Dmaven.test.skip=true + +# 运行已打包的 JAR +cd ruoyi-admin/target +java -jar -Xms256m -Xmx1024m ruoyi-admin.jar + +# 后端服务地址 +http://localhost:8080 + +# Swagger API 文档 +http://localhost:8080/swagger-ui/index.html + +# 测试登录接口获取 token +POST /login/test?username=admin&password=admin123 +``` + +### 前端开发 + +```bash +cd ruoyi-ui + +# 安装依赖 +npm install + +# 开发环境运行(端口 80,代理到 localhost:8080) +npm run dev + +# 生产环境构建 +npm run build:prod + +# 代码检查 +npm run lint +``` + +### 数据库连接 + +```bash +# 通过 MCP MySQL 工具连接 +# 地址: 116.62.17.81:3306 +# 数据库: ibs +# 用户名: root +``` + +## 核心架构 + +### 后端模块结构 + +``` +ruoyi-admin/ # 主入口模块,包含启动类和配置文件 +ruoyi-framework/ # 框架核心:安全配置、缓存、数据源等 +ruoyi-system/ # 系统管理:用户、角色、菜单、字典等 +ruoyi-common/ # 通用工具:工具类、注解、常量等 +ruoyi-quartz/ # 定时任务模块 +ruoyi-generator/ # 代码生成器 +ibs/ # ★ 业务模块:数字支行核心业务 ★ +``` + +### IBS 业务模块 (核心业务) + +位置: `ibs/src/main/java/com/ruoyi/ibs/` + +**主要业务包:** + +| 包名 | 功能 | 说明 | +|------|------|------| +| `grid` | 网格管理 | 支行网格划分、分配、统计 | +| `cmpm` | 客户经理管理 | 客户经理信息维护 | +| `list` | 客户列表管理 | 零售/商户/企业客户管理 | +| `visit` | 走访管理 | 走访任务、记录、轨迹 | +| `task` | 任务管理 | 营销任务分配和跟踪 | +| `draw` | 绘图/网格绘制 | 基于百度地图的网格绘制 | +| `custmap` | 客户地图 | 客户地理分布可视化 | +| `dashboard` | 仪表盘 | 数据统计和展示 | +| `datavisual` | 数据可视化 | 报表和图表 | +| `rules` | 规则配置 | 业务规则配置 | +| `qxhy` | 青县惠银接口 | 外部系统对接 | +| `websocket` | WebSocket通信 | 实时通信支持 | + +**业务模块命名规范:** +- 新建模块命名: `ibs` + 主要功能(如 `ibs-grid`, `ibs-customer`) +- Controller 放在新建模块中,不与若依框架混合 +- Entity 使用 `@Data` 注解 +- Service 使用 `@Resource` 注解,不继承 `ServiceImpl` +- DAO 使用 MyBatis Plus,复杂操作在 XML 中编写 SQL + +### 前端结构 + +``` +ruoyi-ui/src/ +├── api/ # API 接口定义 +├── views/ # 页面视图 +│ ├── grid/ # 网格管理相关页面 +│ ├── customer/ # 客户管理 +│ ├── taskManage/ # 任务管理 +│ ├── dashboard/ # 仪表盘 +│ └── ... +├── components/ # 公共组件 +├── map/ # 地图相关(百度地图集成) +├── store/ # Vuex 状态管理 +└── router/ # 路由配置 +``` + +### 数据库表命名规范 + +- 新建表需加项目前缀: `ibs_` + 表名 +- 示例: `ibs_grid`, `ibs_customer`, `ibs_visit_record` + +## 关键技术点 + +### 1. 地图集成 + +项目深度集成百度地图 API,用于: +- 网格绘制和编辑 +- 客户地理位置标注 +- 走访轨迹记录 +- 客户分布热力图 + +**相关配置:** +- 百度地图 AK 在前端配置 +- 使用 JTS 库进行地理空间计算 + +### 2. 批量导入优化 + +设计批量导入功能时: +- 使用批量操作提高响应速度 +- 导入结果只展示失败数据,不展示成功数据 +- 使用 EasyExcel 处理 Excel + +### 3. 多端支持 + +- PC 端: 主要管理和配置功能 +- PAD 端: 走访记录功能(移动端) + +### 4. 外部系统对接 + +| 系统 | 地址 | 用途 | +|------|------|------| +| 青县惠银 | http://158.234.96.76:5002 | 业务数据对接 | +| BI 系统 | http://158.220.52.42:9388/bi | 数据分析和报表 | +| 阿里云 OSS | - | 文件存储 | + +## 开发规范 + +### 代码分层 + +- **Entity**: 实体类,不继承 BaseEntity,单独添加审计字段 +- **DTO**: 接口传参专用类 +- **VO**: 返回数据专用类 +- **Service**: 业务逻辑,使用 `@Resource` 注入 +- **Mapper**: MyBatis Plus + XML 混合使用 + +### 审计字段 + +通过注解实现自动填充: +```java +@TableField(fill = FieldFill.INSERT) +private String createBy; + +@TableField(fill = FieldFill.INSERT) +private Date createTime; + +@TableField(fill = FieldFill.INSERT_UPDATE) +private String updateBy; + +@TableField(fill = FieldFill.INSERT_UPDATE) +private Date updateTime; +``` + +### 分页 + +使用 MyBatis Plus 分页插件自动处理,传入 `Page` 对象即可。 + +### 前端菜单配置 + +添加新页面后,需要在数据库 `sys_menu` 表中配置菜单权限。 + +## 重要配置文件 + +| 文件 | 位置 | 说明 | +|------|------|------| +| 后端配置 | `ruoyi-admin/src/main/resources/application-dev.yml` | 数据库、Redis、第三方服务配置 | +| 前端配置 | `ruoyi-ui/vue.config.js` | 开发服务器、代理配置 | +| 菜单数据 | 数据库 `sys_menu` 表 | 菜单权限配置 | + +## 测试账号 + +- 用户名: `admin` +- 密码: `admin123` + +## Swagger 接口文档 + +启动后端后访问: `http://localhost:8080/swagger-ui/index.html` + +## 开发流程建议 + +1. **数据库设计**: 新建表需加 `ibs_` 前缀 +2. **后端实体类**: 使用 `@Data` 注解,添加审计字段注解 +3. **后端业务层**: 在 `ibs` 模块下开发,简单 CRUD 用 MyBatis Plus,复杂操作用 XML +4. **后端测试**: 使用 `/login/test` 获取 token 后测试接口 +5. **前端开发**: 在 `ruoyi-ui/views/` 下对应业务模块开发 +6. **菜单配置**: 在 `sys_menu` 表添加菜单项 +7. **API 文档**: 生成后保存在 `doc/api/` 目录 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index fe16427..7144ff8 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -100,6 +100,50 @@ public class SysLoginService return tokenService.createToken(loginUser); } + /** + * 测试登录 + * + * @param username 用户名 + * @param password 密码 + * @return 结果 + */ + public String login(String username, String password) + { + // 登录前置校验 + loginPreCheck(username, password); + // 用户验证 + Authentication authentication = null; + try + { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + catch (Exception e) + { + if (e instanceof BadCredentialsException) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } + } + finally + { + AuthenticationContextHolder.clearContext(); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordLoginInfo(loginUser.getUserId()); + // 生成token + return tokenService.createToken(loginUser); + } + /** * 校验验证码 *