From 1fb945a40f73020eea87f59c2e143c5919e88253 Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Thu, 26 Feb 2026 16:37:37 +0800
Subject: [PATCH 01/10] =?UTF-8?q?redis=E9=85=8D=E7=BD=AE=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-admin/src/main/resources/application-dev.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index 1d98dc5..dc5b8b7 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -79,7 +79,7 @@ spring:
# 地址
host: 116.62.17.81
# 端口,默认为6379
- port: 6379
+ port: 6380
# 数据库索引
database: 0
# 密码
From 3c27b192a4bf85c323525d7c4cb801e515c58bbc Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 15:43:04 +0800
Subject: [PATCH 02/10] claude init
---
CLAUDE.md | 216 ++++++++++++++++++
.../web/service/SysLoginService.java | 44 ++++
2 files changed, 260 insertions(+)
create mode 100644 CLAUDE.md
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);
+ }
+
/**
* 校验验证码
*
From 7efc23dfd2185bd345a7e73536b9afe5cd4b483b Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 15:45:44 +0800
Subject: [PATCH 03/10] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E9=A1=B5=E9=9D=A2?=
=?UTF-8?q?=E6=A0=87=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/.env.development | 2 +-
ruoyi-ui/.env.staging | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development
index 4f6fe95..e1241ca 100644
--- a/ruoyi-ui/.env.development
+++ b/ruoyi-ui/.env.development
@@ -1,5 +1,5 @@
# 页面标题
-VUE_APP_TITLE = UAT支行数智管理平台系统
+VUE_APP_TITLE = DEV支行数智管理平台系统
# 开发环境配置
ENV = 'development'
diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging
index bae4f75..3ce0646 100644
--- a/ruoyi-ui/.env.staging
+++ b/ruoyi-ui/.env.staging
@@ -1,5 +1,5 @@
# 页面标题
-VUE_APP_TITLE = PRE支行数智管理平台系统
+VUE_APP_TITLE = UAT支行数智管理平台系统
NODE_ENV = staging
From 8d2e5386aca984615ee68dbbc1cc23afac6bbb7f Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 16:01:19 +0800
Subject: [PATCH 04/10] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E7=89=B9?=
=?UTF-8?q?=E8=89=B2=E5=8C=BA=E5=9F=9F=E6=9F=A5=E7=9C=8B=E5=AE=A2=E6=88=B7?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=AE=BE=E8=AE=A1=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在特色区域详情窗口添加查看客户按钮的设计方案
- 包含需求分析、技术设计、实施计划、测试计划等内容
---
...2-28-featured-area-customer-view-design.md | 308 ++++++++++++++++++
1 file changed, 308 insertions(+)
create mode 100644 docs/plans/2026-02-28-featured-area-customer-view-design.md
diff --git a/docs/plans/2026-02-28-featured-area-customer-view-design.md b/docs/plans/2026-02-28-featured-area-customer-view-design.md
new file mode 100644
index 0000000..98e8a63
--- /dev/null
+++ b/docs/plans/2026-02-28-featured-area-customer-view-design.md
@@ -0,0 +1,308 @@
+# 特色区域详情窗口添加查看客户功能设计文档
+
+## 文档信息
+
+- **日期**: 2026-02-28
+- **作者**: Claude Code
+- **模块**: 区域绘制 - 特色区域
+- **需求来源**: 用户需求
+
+## 1. 概述
+
+### 1.1 背景
+
+数字支行辅助管理系统的区域绘制功能包含两种区域类型:
+1. **行政区域**(btnType=1):使用 index.vue 页面,区域详情窗口已有"查看客户"按钮
+2. **特色区域**(btnType=2):使用 BMapPolygonEditor.vue 组件,区域详情窗口缺少"查看客户"功能
+
+### 1.2 目标
+
+在特色区域的区域详情窗口中,添加"查看客户"按钮,使功能与行政区域保持一致,方便用户快速查看该区域内的客户信息。
+
+### 1.3 范围
+
+**涉及模块:**
+- 前端:`ruoyi-ui/src/map/BMapPolygonEditor.vue`
+- 复用组件:`ruoyi-ui/src/views/grid/map/draw-area/customer-modal.vue`
+
+**不涉及:**
+- 后端 API 修改
+- 数据库修改
+- 新增文件
+
+## 2. 需求分析
+
+### 2.1 用户需求
+
+在区域绘制的特色区域详情窗口内,添加一个查看客户的按钮,功能与特色区域列表(menulist-modal)中的查看客户功能保持一致。
+
+### 2.2 功能需求
+
+#### 必须实现(MVP)
+- ✅ 在区域详情窗口的按钮区域添加"查看客户"图标按钮
+- ✅ 点击按钮后打开客户查看模态框
+- ✅ 模态框中显示该特色区域的企业、个人、商户客户列表
+- ✅ 支持客户类型切换(企业/个人/商户)
+- ✅ 支持分页查询
+- ✅ 支持点击客户名称跳转到客户详情页
+
+#### 可选功能
+- 无
+
+### 2.3 非功能需求
+
+- **性能**: 不影响页面加载速度
+- **易用性**: 图标按钮风格与现有按钮保持一致
+- **兼容性**: 不影响现有功能
+- **可维护性**: 代码结构清晰,复用现有组件
+
+## 3. 技术设计
+
+### 3.1 整体架构
+
+采用组件复用架构:
+- **展示层**: BMapPolygonEditor.vue(特色区域地图编辑器)
+- **组件层**: CustomerModal.vue(客户查看模态框,已存在)
+- **数据层**: API 接口(shapeCustList,已存在)
+
+### 3.2 方案选择
+
+经过方案对比分析,选择**方案1:添加图标按钮**
+
+**方案对比:**
+
+| 方案 | 优点 | 缺点 | 评分 |
+|------|------|------|------|
+| 方案1:图标按钮 | UI风格一致、改动最小、实现简单 | 图标不如文字明显 | ★★★★★ |
+| 方案2:文字按钮 | 按钮明显、文字清晰 | 可能破坏布局、需要调整样式 | ★★★☆☆ |
+| 方案3:替换布局 | 与行政区域一致 | 改动大、影响用户体验 | ★★☆☆☆ |
+
+### 3.3 数据流程
+
+```
+用户操作流程:
+用户点击特色区域
+ ↓
+显示区域详情窗口(area-info-modal)
+ ↓
+用户点击"查看客户"图标按钮
+ ↓
+触发 previewCustomer() 方法
+ ↓
+调用 this.$refs.customerModal.onOpen()
+ ↓
+CustomerModal 组件接收参数:
+ - cardType="featured" (标识特色区域)
+ - :detailInfo="areaForm" (包含 shapeId)
+ - :btnType="'2'" (特色区域类型)
+ ↓
+CustomerModal 调用 shapeCustList API
+ ↓
+获取并展示客户列表数据
+ ↓
+用户可切换客户类型(企业/个人/商户)
+ ↓
+用户可点击客户名称查看详情
+```
+
+### 3.4 接口设计
+
+**使用现有接口:**
+
+#### 获取特色区域客户列表
+- **接口**: `shapeCustList`
+- **文件**: `@/api/grid/draw-area.js`
+- **参数**:
+ - shapeId: 区域ID
+ - pageNum: 页码
+ - pageSize: 每页条数
+ - custType: 客户类型(0=个人,1=商户,2=企业)
+- **返回**: 客户列表数据
+
+**无需新增接口。**
+
+### 3.5 组件设计
+
+#### BMapPolygonEditor.vue 修改
+
+**1. 引入组件**
+
+```javascript
+import CustomerModal from "@/views/grid/map/draw-area/customer-modal.vue"
+
+export default {
+ components: {
+ // ... 现有组件
+ CustomerModal,
+ },
+}
+```
+
+**2. 添加组件引用**
+
+在 template 末尾(约第273行之后)添加:
+
+```vue
+
+```
+
+**3. 添加图标按钮**
+
+在区域详情窗口的按钮区域(第221-270行),建议位置在"修改信息"按钮之后:
+
+```vue
+
+
+
+```
+
+**4. 添加方法**
+
+```javascript
+methods: {
+ // ... 现有方法
+
+ /**
+ * 查看客户
+ */
+ previewCustomer() {
+ this.$refs.customerModal.onOpen()
+ }
+}
+```
+
+#### CustomerModal.vue(无需修改)
+
+该组件已实现完整的客户查看功能:
+- 支持行政区域(通过 code 查询)
+- 支持特色区域(通过 shapeId 查询)
+- 支持三种客户类型切换
+- 支持分页
+- 支持跳转客户详情
+
+## 4. 实施计划
+
+### 4.1 开发任务
+
+| 任务 | 文件 | 预估时间 | 负责人 |
+|------|------|---------|--------|
+| 添加"查看客户"功能 | BMapPolygonEditor.vue | 0.5h | 前端开发 |
+| 功能测试 | - | 0.5h | 测试人员 |
+
+**总计**: 1小时
+
+### 4.2 测试计划
+
+#### 单元测试
+- 测试 previewCustomer() 方法是否正确调用
+- 测试组件引用是否正确传递参数
+
+#### 集成测试
+- 测试点击按钮后模态框是否正常打开
+- 测试客户列表是否正确加载
+- 测试客户类型切换功能
+- 测试分页功能
+
+#### UI测试
+- 测试图标样式是否一致
+- 测试 tooltip 是否正确显示
+- 测试响应式布局
+
+#### 回归测试
+- 验证现有4个图标按钮功能正常
+- 验证行政区域的查看客户功能正常
+- 验证页面无报错
+
+### 4.3 部署计划
+
+- **开发环境**: 开发完成后立即部署测试
+- **测试环境**: 通过代码审查后部署
+- **生产环境**: 测试通过后部署
+
+## 5. 风险评估
+
+### 5.1 技术风险
+
+| 风险 | 等级 | 影响 | 缓解措施 |
+|------|------|------|----------|
+| 组件引入导致页面加载变慢 | 低 | 轻微 | 组件已在使用,无额外性能影响 |
+| 图标样式不一致 | 低 | 轻微 | 使用现有 icon-area 样式类 |
+| 数据传递错误 | 中 | 中等 | 充分测试,确保 shapeId 正确传递 |
+
+### 5.2 业务风险
+
+| 风险 | 等级 | 影响 | 缓解措施 |
+|------|------|------|----------|
+| 用户体验变化 | 低 | 轻微 | 仅新增功能,不影响现有操作 |
+| 功能误解 | 低 | 轻微 | tooltip 提示清晰 |
+
+## 6. 验收标准
+
+### 6.1 功能验收
+
+- [ ] 区域详情窗口中显示"查看客户"图标按钮
+- [ ] 点击按钮后成功打开客户查看模态框
+- [ ] 模态框顶部显示正确的区域名称和规模
+- [ ] 客户列表正确加载(企业/个人/商户三种类型)
+- [ ] 客户类型切换功能正常
+- [ ] 分页功能正常
+- [ ] 点击客户名称可跳转到客户详情页
+
+### 6.2 UI验收
+
+- [ ] 图标样式与现有图标按钮一致
+- [ ] 图标大小、颜色、间距合理
+- [ ] Tooltip 正确显示"查看客户"
+- [ ] 图标位置合理,不拥挤
+
+### 6.3 性能验收
+
+- [ ] 页面加载速度无明显变化
+- [ ] 模态框打开速度正常(<1秒)
+- [ ] 客户列表加载速度正常(<2秒)
+
+### 6.4 兼容性验收
+
+- [ ] 现有4个图标按钮功能正常
+- [ ] 行政区域的查看客户功能正常
+- [ ] 浏览器控制台无报错
+
+## 7. 后续优化
+
+### 7.1 短期优化(可选)
+
+- 无
+
+### 7.2 长期优化(可选)
+
+1. **统一按钮风格**: 考虑将所有图标按钮改为文字按钮,提高可读性
+2. **权限控制**: 根据用户角色控制"查看客户"按钮的显示/隐藏
+3. **数据缓存**: 对频繁查看的区域客户数据进行缓存,提升加载速度
+
+## 8. 附录
+
+### 8.1 相关文件
+
+- `ruoyi-ui/src/map/BMapPolygonEditor.vue` - 特色区域地图编辑器
+- `ruoyi-ui/src/views/grid/map/draw-area/customer-modal.vue` - 客户查看模态框
+- `ruoyi-ui/src/views/grid/map/draw-area/components/menulist-modal.vue` - 特色区域列表
+- `ruoyi-ui/src/views/grid/map/draw-area/index.vue` - 行政区域页面
+
+### 8.2 参考资料
+
+- Element UI 文档: https://element.eleme.cn/
+- 若依框架文档: http://doc.ruoyi.vip/
+
+### 8.3 变更记录
+
+| 版本 | 日期 | 修改人 | 修改内容 |
+|------|------|--------|----------|
+| 1.0 | 2026-02-28 | Claude Code | 初始版本 |
From c432b040756bb2456a3b0af34c4868c55f2efc8f Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 16:03:35 +0800
Subject: [PATCH 05/10] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E7=89=B9?=
=?UTF-8?q?=E8=89=B2=E5=8C=BA=E5=9F=9F=E6=9F=A5=E7=9C=8B=E5=AE=A2=E6=88=B7?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E6=96=BD=E8=AE=A1=E5=88=92?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 详细的6个任务分解
- 每个步骤包含具体代码和验证方法
- 包含完整的测试流程
- 包含回滚方案
---
.../2026-02-28-featured-area-customer-view.md | 389 ++++++++++++++++++
1 file changed, 389 insertions(+)
create mode 100644 docs/plans/2026-02-28-featured-area-customer-view.md
diff --git a/docs/plans/2026-02-28-featured-area-customer-view.md b/docs/plans/2026-02-28-featured-area-customer-view.md
new file mode 100644
index 0000000..c0bc30d
--- /dev/null
+++ b/docs/plans/2026-02-28-featured-area-customer-view.md
@@ -0,0 +1,389 @@
+# 特色区域查看客户功能实施计划
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**目标:** 在特色区域详情窗口添加"查看客户"图标按钮,复用现有的 customer-modal 组件,实现客户列表查看功能。
+
+**架构:** 组件复用架构 - BMapPolygonEditor.vue 引入 CustomerModal.vue,通过 refs 调用模态框的 onOpen() 方法。
+
+**技术栈:** Vue 2.x, Element UI, 若依框架
+
+**设计文档:** `docs/plans/2026-02-28-featured-area-customer-view-design.md`
+
+---
+
+## 任务 1: 引入 CustomerModal 组件
+
+**文件:**
+- 修改: `ruoyi-ui/src/map/BMapPolygonEditor.vue:20-30`(import 区域)
+
+**步骤 1: 在 script 标签内添加 import 语句**
+
+在第22行(MenuEdit 导入语句之后)添加:
+
+```javascript
+import CustomerModal from "@/views/grid/map/draw-area/customer-modal.vue"
+```
+
+**步骤 2: 在 components 中注册组件**
+
+在第26-30行的 components 对象中添加 CustomerModal:
+
+```javascript
+components: {
+ MenuEdit,
+ BMapPolygonEditor,
+ MenuEdit,
+ CustomerModal, // 新增
+},
+```
+
+**步骤 3: 验证 import 路径正确**
+
+运行前端项目验证无报错:
+
+```bash
+cd ruoyi-ui
+npm run dev
+```
+
+预期: 浏览器控制台无 "Failed to mount component" 错误
+
+**步骤 4: 提交代码**
+
+```bash
+git add ruoyi-ui/src/map/BMapPolygonEditor.vue
+git commit -m "feat(featured-areas): 引入 CustomerModal 组件"
+```
+
+---
+
+## 任务 2: 在 template 中添加组件引用
+
+**文件:**
+- 修改: `ruoyi-ui/src/map/BMapPolygonEditor.vue:270-275`(template 末尾)
+
+**步骤 1: 在 template 末尾添加组件标签**
+
+在第273行(`` 之后,`
` 之前)添加:
+
+```vue
+
+
+
+
+```
+
+**步骤 2: 验证组件引用**
+
+在浏览器中打开特色区域页面,验证控制台无报错。
+
+**步骤 3: 验证 props 传递**
+
+在 Vue DevTools 中检查 customer-modal 组件的 props:
+- cardType 应该是 "featured"
+- detailInfo 应该是 areaForm 对象
+- btnType 应该是 "2"
+
+**步骤 4: 提交代码**
+
+```bash
+git add ruoyi-ui/src/map/BMapPolygonEditor.vue
+git commit -m "feat(featured-areas): 添加 CustomerModal 组件引用"
+```
+
+---
+
+## 任务 3: 在区域详情窗口添加查看客户图标按钮
+
+**文件:**
+- 修改: `ruoyi-ui/src/map/BMapPolygonEditor.vue:221-240`(edit-operate 按钮区域)
+
+**步骤 1: 定位按钮插入位置**
+
+找到第221-240行的代码区域,这是 `infoType === 'SHOW'` 的按钮区域:
+- 第229行:修改信息按钮结束
+- 第240行:删除区域按钮开始
+
+我们需要在修改信息按钮之后插入查看客户按钮。
+
+**步骤 2: 添加查看客户图标按钮**
+
+在第239行(修改信息 tooltip 结束)之后,第240行(删除区域 tooltip 开始)之前插入:
+
+```vue
+
+
+
+
+
+
+
+```
+
+**步骤 3: 验证图标样式**
+
+在浏览器中:
+1. 打开特色区域页面
+2. 点击一个已绘制的区域
+3. 查看区域详情窗口底部的图标按钮区域
+4. 验证新添加的"用户图标"样式与其他图标一致
+
+**步骤 4: 验证 tooltip 显示**
+
+1. 鼠标悬停在新添加的用户图标上
+2. 验证 tooltip 显示"查看客户"
+3. 验证 tooltip 样式与其他 tooltip 一致
+
+**步骤 5: 提交代码**
+
+```bash
+git add ruoyi-ui/src/map/BMapPolygonEditor.vue
+git commit -m "feat(featured-areas): 添加查看客户图标按钮"
+```
+
+---
+
+## 任务 4: 实现 previewCustomer 方法
+
+**文件:**
+- 修改: `ruoyi-ui/src/map/BMapPolygonEditor.vue:900-1000`(methods 区域)
+
+**步骤 1: 定位 methods 区域**
+
+找到 methods 对象的最后,准备添加新方法。建议添加在 `updateAreaShape()` 方法之后。
+
+**步骤 2: 添加 previewCustomer 方法**
+
+在 methods 对象中添加:
+
+```javascript
+ /**
+ * 调整边界
+ */
+ updateAreaShape() {
+ // ... 现有代码
+ },
+ /**
+ * 查看客户
+ */
+ previewCustomer() {
+ this.$refs.customerModal.onOpen()
+ }
+```
+
+**步骤 3: 验证方法调用**
+
+在浏览器控制台中测试:
+1. 打开特色区域页面
+2. 点击一个区域,打开区域详情窗口
+3. 打开 Vue DevTools
+4. 找到 BMapPolygonEditor 组件
+5. 在控制台执行:`$vm0.previewCustomer()`
+6. 验证 customer-modal 模态框成功打开
+
+**步骤 4: 提交代码**
+
+```bash
+git add ruoyi-ui/src/map/BMapPolygonEditor.vue
+git commit -m "feat(featured-areas): 实现 previewCustomer 方法"
+```
+
+---
+
+## 任务 5: 功能测试
+
+**文件:**
+- 无需修改文件
+
+**步骤 1: 启动前端项目**
+
+```bash
+cd ruoyi-ui
+npm run dev
+```
+
+预期: 项目成功启动在 http://localhost:80
+
+**步骤 2: 登录系统**
+
+1. 访问 http://localhost:80
+2. 使用测试账号登录:
+ - 用户名: admin
+ - 密码: admin123
+
+**步骤 3: 进入特色区域页面**
+
+1. 导航到"网格管理" > "区域绘制"
+2. 点击"特色区域"标签(btnType=2)
+3. 等待地图加载完成
+
+**步骤 4: 测试查看客户按钮**
+
+1. 在左侧菜单中选择一个特色区域图层
+2. 在地图上点击一个已绘制的特色区域
+3. 验证右上角弹出区域详情窗口
+4. 查看窗口底部的图标按钮区域
+5. 验证显示"用户图标"(查看客户按钮)
+
+**步骤 5: 测试点击功能**
+
+1. 点击"查看客户"图标
+2. 验证:
+ - customer-modal 对话框成功打开
+ - 对话框标题显示"查看客户"
+ - 顶部显示区域名称和规模信息
+ - 客户列表成功加载
+ - 显示三种客户类型标签(企业/个人/商户)
+
+**步骤 6: 测试客户类型切换**
+
+1. 点击"个人"标签
+2. 验证客户列表刷新,显示个人客户
+3. 点击"商户"标签
+4. 验证客户列表刷新,显示商户客户
+5. 点击"企业"标签
+6. 验证客户列表刷新,显示企业客户
+
+**步骤 7: 测试分页功能**
+
+1. 如果客户数量超过10条,验证分页器显示
+2. 点击下一页
+3. 验证客户列表刷新,显示第二页数据
+4. 修改每页显示条数
+5. 验证列表重新加载
+
+**步骤 8: 测试客户详情跳转**
+
+1. 点击表格中的客户名称(el-button)
+2. 验证路由跳转到客户详情页面
+3. 验证详情页面显示正确的客户信息
+
+**步骤 9: 测试现有功能兼容性**
+
+1. 关闭客户模态框
+2. 依次点击其他4个图标按钮:
+ - 重新申请
+ - 修改信息
+ - 删除区域
+ - 调整边界
+3. 验证这些按钮功能正常,无报错
+
+**步骤 10: 测试行政区域兼容性**
+
+1. 切换到"行政区域"标签(btnType=1)
+2. 点击一个行政区域
+3. 验证行政区域的"查看客户"按钮功能正常
+4. 验证两个区域类型的查看客户功能互不影响
+
+**步骤 11: 检查浏览器控制台**
+
+1. 打开浏览器开发者工具
+2. 切换到 Console 标签
+3. 执行所有测试步骤
+4. 验证控制台无 JavaScript 报错
+5. 验证控制台无 Vue 警告
+
+**步骤 12: 最终提交**
+
+如果所有测试通过:
+
+```bash
+git status
+```
+
+预期: 无未提交的文件
+
+---
+
+## 任务 6: 更新文档(可选)
+
+**文件:**
+- 修改: `docs/plans/2026-02-28-featured-area-customer-view-design.md`
+
+**步骤 1: 更新验收标准**
+
+在验收标准的各项前打勾:
+
+```markdown
+### 6.1 功能验收
+
+- [x] 区域详情窗口中显示"查看客户"图标按钮
+- [x] 点击按钮后成功打开客户查看模态框
+- [x] 模态框顶部显示正确的区域名称和规模
+- [x] 客户列表正确加载(企业/个人/商户三种类型)
+- [x] 客户类型切换功能正常
+- [x] 分页功能正常
+- [x] 点击客户名称可跳转到客户详情页
+
+### 6.2 UI验收
+
+- [x] 图标样式与现有图标按钮一致
+- [x] 图标大小、颜色、间距合理
+- [x] Tooltip 正确显示"查看客户"
+- [x] 图标位置合理,不拥挤
+
+### 6.3 性能验收
+
+- [x] 页面加载速度无明显变化
+- [x] 模态框打开速度正常(<1秒)
+- [x] 客户列表加载速度正常(<2秒)
+
+### 6.4 兼容性验收
+
+- [x] 现有4个图标按钮功能正常
+- [x] 行政区域的查看客户功能正常
+- [x] 浏览器控制台无报错
+```
+
+**步骤 2: 提交文档更新**
+
+```bash
+git add docs/plans/2026-02-28-featured-area-customer-view-design.md
+git commit -m "docs: 更新特色区域查看客户功能验收状态"
+```
+
+---
+
+## 完成检查清单
+
+实施完成后,验证以下内容:
+
+- [ ] 所有6个任务已完成
+- [ ] 所有 git commits 已提交
+- [ ] 前端项目无编译错误
+- [ ] 浏览器控制台无 JavaScript 错误
+- [ ] 功能测试全部通过
+- [ ] 代码已推送到远程仓库(如需要)
+
+## 回滚方案
+
+如果实施过程中遇到问题,可以回滚:
+
+```bash
+# 查看提交历史
+git log --oneline
+
+# 回滚到指定提交(替换 为实际的 commit hash)
+git reset --hard
+
+# 或者回滚所有提交(回到初始状态)
+git reset --hard HEAD~4
+```
+
+## 相关资源
+
+- **设计文档**: `docs/plans/2026-02-28-featured-area-customer-view-design.md`
+- **修改文件**: `ruoyi-ui/src/map/BMapPolygonEditor.vue`
+- **复用组件**: `ruoyi-ui/src/views/grid/map/draw-area/customer-modal.vue`
+- **参考实现**: `ruoyi-ui/src/views/grid/map/draw-area/components/menulist-modal.vue:413-416`
+- **Element UI 文档**: https://element.eleme.cn/#/zh-CN/component/tooltip
+- **Vue 2.x 文档**: https://v2.cn.vuejs.org/
From 4ec15446606cdee03b0ee45d970c0d0c87d4ed72 Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 16:10:39 +0800
Subject: [PATCH 06/10] =?UTF-8?q?feat(featured-areas):=20=E5=BC=95?=
=?UTF-8?q?=E5=85=A5=20CustomerModal=20=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/src/map/BMapPolygonEditor.vue | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ruoyi-ui/src/map/BMapPolygonEditor.vue b/ruoyi-ui/src/map/BMapPolygonEditor.vue
index cf4bb52..e521325 100644
--- a/ruoyi-ui/src/map/BMapPolygonEditor.vue
+++ b/ruoyi-ui/src/map/BMapPolygonEditor.vue
@@ -337,6 +337,7 @@ import { businessBelongList } from '@/views/grid/create/utils'
import { mapGetters } from 'vuex'
import { Message } from 'element-ui'
import { isEmpty } from 'lodash'
+import CustomerModal from '@/views/grid/map/draw-area/customer-modal.vue'
const polygonOptions = {
strokeColor: '#5E87DB',
strokeWeight: 3,
@@ -355,6 +356,9 @@ const labelOptions = {
}
export default {
name: 'BMapPolygonEditor',
+ components: {
+ CustomerModal
+ },
props: ['layerInfo'],
data() {
return {
From b15cc4fdcb851839bc7e99d92a471c0e967687b3 Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 16:19:05 +0800
Subject: [PATCH 07/10] =?UTF-8?q?feat(featured-areas):=20=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=20CustomerModal=20=E7=BB=84=E4=BB=B6=E5=BC=95?=
=?UTF-8?q?=E7=94=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/src/map/BMapPolygonEditor.vue | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ruoyi-ui/src/map/BMapPolygonEditor.vue b/ruoyi-ui/src/map/BMapPolygonEditor.vue
index e521325..d654715 100644
--- a/ruoyi-ui/src/map/BMapPolygonEditor.vue
+++ b/ruoyi-ui/src/map/BMapPolygonEditor.vue
@@ -271,6 +271,13 @@
+
+
From 67e14363e34d8e88a62285f99dbddd8472fa74eb Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Sat, 28 Feb 2026 16:26:34 +0800
Subject: [PATCH 08/10] =?UTF-8?q?feat(featured-areas):=20=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E6=9F=A5=E7=9C=8B=E5=AE=A2=E6=88=B7=E5=9B=BE=E6=A0=87?=
=?UTF-8?q?=E6=8C=89=E9=92=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/src/map/BMapPolygonEditor.vue | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ruoyi-ui/src/map/BMapPolygonEditor.vue b/ruoyi-ui/src/map/BMapPolygonEditor.vue
index d654715..e5ade47 100644
--- a/ruoyi-ui/src/map/BMapPolygonEditor.vue
+++ b/ruoyi-ui/src/map/BMapPolygonEditor.vue
@@ -237,6 +237,14 @@
@click.stop="updateAreaInfo"
/>
+
+
+
+
+
Date: Sat, 28 Feb 2026 16:34:29 +0800
Subject: [PATCH 09/10] =?UTF-8?q?feat(featured-areas):=20=E5=AE=9E?=
=?UTF-8?q?=E7=8E=B0=20previewCustomer=20=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/src/map/BMapPolygonEditor.vue | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ruoyi-ui/src/map/BMapPolygonEditor.vue b/ruoyi-ui/src/map/BMapPolygonEditor.vue
index e5ade47..aa41a1c 100644
--- a/ruoyi-ui/src/map/BMapPolygonEditor.vue
+++ b/ruoyi-ui/src/map/BMapPolygonEditor.vue
@@ -1226,6 +1226,12 @@ export default {
this.$store.dispatch('setIsDrawing', true)
this.currentPolygon.enableEditing()
},
+ /**
+ * 查看客户
+ */
+ previewCustomer() {
+ this.$refs.customerModal.onOpen()
+ },
setForm(data) {
this.areaForm = data
this.visible = true
From d897e1233539564e25e9b4bc6375425d0a040d6b Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Fri, 6 Mar 2026 13:38:05 +0800
Subject: [PATCH 10/10] =?UTF-8?q?=E5=9C=B0=E5=9B=BEkey?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/public/baidu/anchor.html | 2 +-
ruoyi-ui/public/baidu/area.html | 2 +-
ruoyi-ui/public/baidu/grid.html | 2 +-
ruoyi-ui/public/baidu/huitu-quhua.html | 2 +-
ruoyi-ui/public/baidu/huitu.html | 2 +-
ruoyi-ui/public/baidu/index.html | 2 +-
ruoyi-ui/public/baidu/marker.html | 2 +-
ruoyi-ui/public/baidu/regionSelect.html | 2 +-
ruoyi-ui/public/index.html | 3 ++-
ruoyi-ui/src/map/BaiduHuiTu.vue | 4 ++--
10 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/ruoyi-ui/public/baidu/anchor.html b/ruoyi-ui/public/baidu/anchor.html
index 446d47b..30508e0 100644
--- a/ruoyi-ui/public/baidu/anchor.html
+++ b/ruoyi-ui/public/baidu/anchor.html
@@ -18,7 +18,7 @@
diff --git a/ruoyi-ui/public/baidu/huitu.html b/ruoyi-ui/public/baidu/huitu.html
index 8c1141b..2613d62 100644
--- a/ruoyi-ui/public/baidu/huitu.html
+++ b/ruoyi-ui/public/baidu/huitu.html
@@ -39,7 +39,7 @@
+
diff --git a/ruoyi-ui/src/map/BaiduHuiTu.vue b/ruoyi-ui/src/map/BaiduHuiTu.vue
index 39b6a5d..f04e15f 100644
--- a/ruoyi-ui/src/map/BaiduHuiTu.vue
+++ b/ruoyi-ui/src/map/BaiduHuiTu.vue
@@ -35,7 +35,7 @@ export default {
initSdk(){
this.sdk = new QuHuaSdk({
ak: 'L7KaAZUYPVSD40nYT09rWWgIdZKUesiX',
- webAk: 't6k6UC2IZR40Un8kkqM4RXlaQb4FulyM',
+ webAk: 'mokVj0S4sGE9av6NBwy8WHY0xnQsucbE',
domId: 'box',
defaultCenterCity: "杭州市", // 非必填
_baseUrl: "http://158.234.96.76:5001/logisticsWeb-quhua-intranet", // 固定格式,必填
@@ -137,7 +137,7 @@ export default {
onChange(){
this.sdk = new QuHuaSdk({
ak: 'L7KaAZUYPVSD40nYT09rWWgIdZKUesiX',
- webAk: 't6k6UC2IZR40Un8kkqM4RXlaQb4FulyM',
+ webAk: 'mokVj0S4sGE9av6NBwy8WHY0xnQsucbE',
domId: 'box',
defaultCenterCity: "杭州市", // 非必填
_baseUrl: "http://158.234.96.76:5001/logisticsWeb-quhua-intranet", // 固定格式,必填