feat: 查询接口改为key
This commit is contained in:
parent
3007b73d77
commit
8552deddda
BIN
docs/listUserByQy接口说明.docx
Normal file
BIN
docs/listUserByQy接口说明.docx
Normal file
Binary file not shown.
94
docs/listUserByQy接口说明.md
Normal file
94
docs/listUserByQy接口说明.md
Normal file
@ -0,0 +1,94 @@
|
||||
# `POST /mhzc/user/listUserByQy` 接口说明
|
||||
|
||||
按企业名称与登录账号模糊查询用户-企业匹配项。
|
||||
|
||||
## 基本信息
|
||||
|
||||
| 项 | 说明 |
|
||||
| ---------------------- | ----------------------------------- |
|
||||
| **请求方法** | `POST` |
|
||||
| **路径** | `/mhzc/user/listUserByQy` |
|
||||
| **Content-Type** | `application/json; charset=UTF-8` |
|
||||
| **鉴权** | 需要携带登录信息 |
|
||||
|
||||
## 入参 `UserQyReqVO`
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| ------------ | ------- | ---- | ------------------------------------------ |
|
||||
| `key` | String | 是 | 模糊匹配关键字,对登录账号或企业名称命中任一即返回;为空时返回空结果 |
|
||||
| `pageNo` | Integer | 是 | 页码(从 1 开始) |
|
||||
| `pageSize` | Integer | 是 | 每页大小,(建议传10) |
|
||||
|
||||
**示例请求体:**
|
||||
|
||||
```json
|
||||
{
|
||||
"key": "上海链坤",
|
||||
"pageNo": 1,
|
||||
"pageSize": 10
|
||||
}
|
||||
```
|
||||
|
||||
**入参规则:**
|
||||
|
||||
- `key` 为空字符串或 null → 返回空结果(`records=[]`,`total=0`)
|
||||
- `key` 非空 → 对 `dlzh`(登录账号)和 `qymc`(企业名称)做 `OR` 模糊匹配,命中任一即返回
|
||||
|
||||
## 返回结果
|
||||
|
||||
外层结构 `CommonResult`:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| -------- | ---------------- | ---------------------- |
|
||||
| `code` | Integer | 业务码,`0` 表示成功 |
|
||||
| `msg` | String | 提示信息 |
|
||||
| `data` | Page\<UserQyVO\> | 分页结果 |
|
||||
|
||||
分页 `Page<UserQyVO>`:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| ----------- | ---------------- | -------- |
|
||||
| `total` | Long | 总记录数 |
|
||||
| `current` | Long | 当前页码 |
|
||||
| `size` | Long | 每页大小 |
|
||||
| `pages` | Long | 总页数 |
|
||||
| `records` | List\<UserQyVO\> | 数据列表 |
|
||||
|
||||
每条记录 `UserQyVO`:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| -------- | ------ | -------- |
|
||||
| `dlzh` | String | 登录账号 |
|
||||
| `qymc` | String | 企业名称 |
|
||||
|
||||
**示例响应体:**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"total": 42,
|
||||
"current": 1,
|
||||
"size": 10,
|
||||
"pages": 5,
|
||||
"records": [
|
||||
{ "dlzh": "user001@qy", "qymc": "上海链坤数字科技有限公司" },
|
||||
{ "dlzh": "user001@qy", "qymc": "上海链坤集团" }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 行为说明
|
||||
|
||||
- **一个用户可关联多个企业**:匹配结果中 `dlzh` 可能重复,每个企业占一行
|
||||
- **空结果**:返回 HTTP 200,`records=[]`,`total=0`,不抛业务异常
|
||||
|
||||
## 错误码
|
||||
|
||||
| 场景 | HTTP | code | msg |
|
||||
| ------------- | ---- | ---- | --------------- |
|
||||
| 成功 | 200 | 0 | ok |
|
||||
| 请求体非 JSON | 400 | — | Spring 默认错误 |
|
||||
| 系统异常 | 200 | 500 | "系统异常:..." |
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
**Goal:** 在 `txw-mhzc` 模块新增 `POST /user/listUserByQy` 接口,按 `dlzh`(登录账号)与 `qymc`(企业名称)模糊查询用户-企业匹配项并分页返回。
|
||||
|
||||
**Architecture:** 单条三表 JOIN SQL(`yhxxb` ⨝ `yhqygxb` ⨝ `qyxxb`),写在 `TxwMhzcYhxxbMapper.xml` 中,Mapper 接口显式接收 `IPage` 参数以触发 MyBatis-Plus 分页拦截器注入 LIMIT 与 COUNT(*)。Controller → Service → Mapper 三层调用,与现有 `getAllUser` 完全同构。
|
||||
**Architecture:** 单条三表 JOIN SQL(`yhxxb` ⨝ `yhqygxb` ⨝ `qyxxb`),写在 `TxwMhzcYhxxbMapper.xml` 中,Mapper 接口显式接收 `IPage` 参数以触发 MyBatis-Plus 分页拦截器注入 LIMIT 与 COUNT(*)。Controller → Service → Mapper 三层调用,与现有 `getAllUser` 完全同构。SQL 用 `<choose>` 实现"OR 模糊匹配 + 空 key 返回空"的语义。
|
||||
|
||||
**Tech Stack:**
|
||||
- Spring Boot + MyBatis-Plus 3.x(项目内 BaseMapperX + IService)
|
||||
@ -19,10 +19,11 @@
|
||||
- 模块归属:`txw-mhzc`,所有改动只动该模块
|
||||
- 包路径:`com.css.txw.mhzc`
|
||||
- 入参 `UserQyReqVO` 继承 `com.css.ggzc.framework.common.pojo.PageParam`
|
||||
- 入参字段:单个 `String key`,对 `y.dlzh` 与 `q.qymc` 做 **OR 模糊匹配**;`key` 为空字符串或 null 时返回空结果(SQL `<otherwise> AND 1=0 </otherwise>` 短路保证)
|
||||
- 出参 `Page<UserQyVO>` 由 `com.baomidou.mybatisplus.extension.plugins.pagination.Page` 承载
|
||||
- 接口路径:`POST /user/listUserByQy`(与 `UserController` 同前缀)
|
||||
- 过滤硬性条件:`y.yxbz = 'Y' AND y.sdbz = 'N'`(与 `getYhxxByDlzh` 等现有查询一致)
|
||||
- 模糊匹配:`LIKE CONCAT('%', #{reqVO.xxx}, '%')`;`#{...}` 走预编译,SQL 注入安全
|
||||
- 模糊匹配:`LIKE CONCAT('%', #{reqVO.key}, '%')`;`#{...}` 走预编译,SQL 注入安全
|
||||
- 排序:`ORDER BY y.lrrq DESC`
|
||||
- 一个用户关联多个企业 → 结果中 dlzh 重复出现,每个企业占一行
|
||||
- 项目无单测基建,按规格 §8 的 9 项手动验证清单作为验收标准
|
||||
@ -51,7 +52,7 @@
|
||||
**Interfaces:**
|
||||
- Consumes: 无(最底层数据载体)
|
||||
- Produces:
|
||||
- `UserQyReqVO extends PageParam { String dlzh; String qymc; }`
|
||||
- `UserQyReqVO extends PageParam { String key; }`
|
||||
- `UserQyVO { String dlzh; String qymc; }`
|
||||
|
||||
- [ ] **Step 1: 创建 `UserQyReqVO.java`**
|
||||
@ -69,11 +70,8 @@ import lombok.Data;
|
||||
@Data
|
||||
public class UserQyReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "登录账号(模糊匹配,可空)")
|
||||
private String dlzh;
|
||||
|
||||
@Schema(description = "企业名称(模糊匹配,可空)")
|
||||
private String qymc;
|
||||
@Schema(description = "关键字,对登录账号或企业名称做模糊匹配(必填,为空时返回空结果)")
|
||||
private String key;
|
||||
}
|
||||
```
|
||||
|
||||
@ -161,18 +159,22 @@ Page<UserQyVO> listUserByQy(IPage<UserQyVO> page, @Param("reqVO") UserQyReqVO re
|
||||
JOIN txw_mhzc_yhqygxb g ON g.yh_uuid = y.yh_uuid
|
||||
JOIN txw_mhzc_qyxxb q ON q.qyuuid = g.qyuuid
|
||||
WHERE y.yxbz = 'Y' AND y.sdbz = 'N'
|
||||
<if test="reqVO.dlzh != null and reqVO.dlzh != ''">
|
||||
AND y.dlzh LIKE CONCAT('%', #{reqVO.dlzh}, '%')
|
||||
</if>
|
||||
<if test="reqVO.qymc != null and reqVO.qymc != ''">
|
||||
AND q.qymc LIKE CONCAT('%', #{reqVO.qymc}, '%')
|
||||
</if>
|
||||
<choose>
|
||||
<when test="reqVO.key != null and reqVO.key != ''">
|
||||
AND (y.dlzh LIKE CONCAT('%', #{reqVO.key}, '%')
|
||||
OR q.qymc LIKE CONCAT('%', #{reqVO.key}, '%'))
|
||||
</when>
|
||||
<otherwise>
|
||||
AND 1 = 0
|
||||
</otherwise>
|
||||
</choose>
|
||||
ORDER BY y.lrrq DESC
|
||||
</select>
|
||||
```
|
||||
|
||||
> **关键说明**:
|
||||
> - 因为 mapper 参数加了 `@Param("reqVO")`,XML 内 `<if test>` 与 `#{...}` 都必须用 `reqVO.dlzh` / `reqVO.qymc` 限定,不能直接写 `dlzh` / `qymc`
|
||||
> - 因为 mapper 参数加了 `@Param("reqVO")`,XML 内 `<if test>` 与 `#{...}` 都必须用 `reqVO.key` 限定
|
||||
> - `<choose>` 分支保证 `key` 为空时 SQL 必定返回空(`AND 1=0` 短路),不依赖调用方传非空
|
||||
> - `resultType` 必须写 VO 类的完全限定名,否则 MyBatis 无法实例化结果
|
||||
> - `yxbz='Y' AND sdbz='N'` 是与现有 `getYhxxByDlzh`、`getYhxxByYhuuid` 等查询一致的硬性过滤条件
|
||||
|
||||
@ -308,113 +310,67 @@ git commit -m "feat(mhzc): 暴露 POST /user/listUserByQy 端点"
|
||||
- 端口、网关、Swagger UI 路径以项目 `application.yaml` / `bootstrap-local.yml` 为准
|
||||
- 数据库存在测试数据:至少有 1 个有效用户(`yxbz='Y' AND sdbz='N'`)关联 2 个企业,1 个被锁定用户,1 个无效用户
|
||||
|
||||
- [ ] **Step 1: 验证空入参**
|
||||
- [ ] **Step 1: 验证 `key` 为空返回空结果**
|
||||
|
||||
请求:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"","qymc":"","pageNo":1,"pageSize":10}'
|
||||
-H "Content-Type: application/json; charset=UTF-8" \
|
||||
--data-binary @verify-listUserByQy-empty.json
|
||||
```
|
||||
|
||||
预期:HTTP 200,`code=0`,`data.total` ≥ 1,`data.records` 中所有 `dlzh` 都属于有效用户。
|
||||
文件内容:`{"key":"","pageNo":1,"pageSize":10}`
|
||||
|
||||
- [ ] **Step 2: 验证只按 `dlzh` 模糊匹配**
|
||||
预期:HTTP 200,`code=0`,`data.records=[]`,`data.total=0`(由 SQL `AND 1=0` 短路保证)。
|
||||
|
||||
请求:
|
||||
- [ ] **Step 2: 验证 `key` 命中 `dlzh`(OR)**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"<某个已知账号前缀>","qymc":"","pageNo":1,"pageSize":10}'
|
||||
```
|
||||
请求(用文件 `verify-listUserByQy-dlzh.json`,内容 `{"key":"<已知账号前缀>","pageNo":1,"pageSize":10}`):
|
||||
|
||||
预期:`data.records[*].dlzh` 都包含该前缀;`qymc` 不影响结果。
|
||||
预期:`data.records[*].dlzh` 都包含该前缀;`qymc` 是否命中不影响结果。
|
||||
|
||||
- [ ] **Step 3: 验证只按 `qymc` 模糊匹配**
|
||||
- [ ] **Step 3: 验证 `key` 命中 `qymc`(OR)**
|
||||
|
||||
请求:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"","qymc":"<某个已知企业名称子串>","pageNo":1,"pageSize":10}'
|
||||
```
|
||||
请求(用文件 `verify-listUserByQy-qymc.json`,内容 `{"key":"<已知企业名称子串>","pageNo":1,"pageSize":10}`):
|
||||
|
||||
预期:`data.records[*].qymc` 都包含该子串。
|
||||
|
||||
- [ ] **Step 4: 验证 `dlzh` 与 `qymc` 同时生效(AND)**
|
||||
- [ ] **Step 4: 验证 `key` 同时命中 `dlzh` 与 `qymc`(OR)**
|
||||
|
||||
请求:
|
||||
请求(用文件 `verify-listUserByQy-both.json`,内容 `{"key":"<账号或企业名中存在的子串>","pageNo":1,"pageSize":10}`):
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"<某个已知账号前缀>","qymc":"<某个已知企业名称子串>","pageNo":1,"pageSize":10}'
|
||||
```
|
||||
|
||||
预期:`data.records` 同时满足两个条件。
|
||||
预期:`data.records` 包含命中任一字段的所有项。
|
||||
|
||||
- [ ] **Step 5: 验证多企业用户返回多行**
|
||||
|
||||
请求:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"<关联 2 个企业的那个账号>","qymc":"","pageNo":1,"pageSize":10}'
|
||||
```
|
||||
请求(用文件 `verify-listUserByQy-multi.json`,内容 `{"key":"<关联 2 个企业的那个账号>","pageNo":1,"pageSize":10}`):
|
||||
|
||||
预期:`data.records` 中该 `dlzh` 出现 2 次,分别对应 2 个不同的 `qymc`。
|
||||
|
||||
- [ ] **Step 6: 验证锁定用户被过滤**
|
||||
|
||||
请求:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"<被锁定用户账号>","qymc":"","pageNo":1,"pageSize":10}'
|
||||
```
|
||||
请求(用文件 `verify-listUserByQy-locked.json`,内容 `{"key":"<被锁定用户账号>","pageNo":1,"pageSize":10}`):
|
||||
|
||||
预期:`data.records` 为空(被 `sdbz='N'` 过滤条件排除)。
|
||||
|
||||
- [ ] **Step 7: 验证无效用户被过滤**
|
||||
|
||||
请求:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"<无效用户账号>","qymc":"","pageNo":1,"pageSize":10}'
|
||||
```
|
||||
请求(用文件 `verify-listUserByQy-invalid.json`,内容 `{"key":"<无效用户账号>","pageNo":1,"pageSize":10}`):
|
||||
|
||||
预期:`data.records` 为空(被 `yxbz='Y'` 过滤条件排除)。
|
||||
|
||||
- [ ] **Step 8: 验证 SQL 注入安全**
|
||||
|
||||
请求:
|
||||
请求(用文件 `verify-listUserByQy-inject.json`,内容 `{"key":"%' OR '1'='1","pageNo":1,"pageSize":10}`):
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"dlzh\":\"%' OR '1'='1\",\"qymc\":\"\",\"pageNo\":1,\"pageSize\":10}"
|
||||
```
|
||||
|
||||
预期:HTTP 200,无 500 错误。`#{...}` 走预编译,转义后只匹配字面量 `'%' OR '1'='1'`,结果为空或仅含恰好等于该字面量的 dlzh(数据库无此账号时为空)。
|
||||
预期:HTTP 200,无 500 错误。`#{...}` 走预编译,转义后只匹配字面量 `'%' OR '1'='1'`,结果为空(数据库无此关键字时)。注意:`#{}` 不会转义 LIKE 元字符,因此输入中若含 `%` 或 `_` 仍会按 MySQL 通配符匹配。
|
||||
|
||||
- [ ] **Step 9: 验证分页边界**
|
||||
|
||||
请求:
|
||||
请求(用文件 `verify-listUserByQy-page.json`,内容 `{"key":"<已知子串>","pageNo":99999,"pageSize":10}`):
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dlzh":"","qymc":"","pageNo":99999,"pageSize":10}'
|
||||
```
|
||||
|
||||
预期:`data.records` 为空数组,`data.total` 仍正确(与 Step 1 一致),`data.current` 为 99999。
|
||||
预期:`data.records` 为空数组,`data.total` 仍正确(与 Step 4 命中数一致),`data.current` 为 99999。
|
||||
|
||||
- [ ] **Step 10: 验收确认**
|
||||
|
||||
@ -438,7 +394,7 @@ curl -X POST http://localhost:<port>/user/listUserByQy \
|
||||
**2. 占位符扫描:** 无 TBD / TODO / "implement later" / "类似 Task N"。
|
||||
|
||||
**3. 类型一致性:**
|
||||
- `UserQyReqVO.dlzh` / `UserQyReqVO.qymc` 在 Task 1 定义,Task 2 SQL 用 `reqVO.dlzh` / `reqVO.qymc` 引用,Task 3-4 方法签名一致
|
||||
- `UserQyReqVO.key` 在 Task 1 定义,Task 2 SQL 用 `reqVO.key` 引用,Task 3-4 方法签名一致
|
||||
- `Page<UserQyVO>` 在 Task 1 定义,Task 2 mapper 返回、Task 3 service 返回、Task 4 controller 返回,全程一致
|
||||
- `@Param("reqVO")` 在 Task 2 mapper 声明,Task 2 XML 内 `reqVO.dlzh` 一致
|
||||
- `PageParam#getPageNo()` / `PageParam#getPageSize()` 是项目内既有方法,Task 3 service 复用
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
新增一个按企业名称(及登录账号)查询用户的接口:
|
||||
|
||||
- 入参:`dlzh`(登录账号,可空)、`qymc`(企业名称,可空),均为**模糊匹配**
|
||||
- 入参:单个 `key` 关键字,对 `dlzh`(登录账号)或 `qymc`(企业名称)做 **OR 模糊匹配**;`key` 为空时返回空结果
|
||||
- 出参:符合条件的 `dlzh` + `qymc` 列表,分页返回
|
||||
- 一个用户可关联多个企业,匹配结果**每个企业一条记录**(dlzh 可重复)
|
||||
|
||||
@ -43,12 +43,11 @@ Content-Type: application/json
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `dlzh` | String | 否 | 登录账号模糊匹配关键字 |
|
||||
| `qymc` | String | 否 | 企业名称模糊匹配关键字 |
|
||||
| `key` | String | 是 | 模糊匹配关键字,对 `dlzh` 或 `qymc` 任一命中即返回 |
|
||||
| `pageNo` | Integer | 是 | 页码(继承 `PageParam`) |
|
||||
| `pageSize` | Integer | 是 | 每页大小(继承 `PageParam`) |
|
||||
|
||||
`dlzh` 与 `qymc` 同时为空时,返回所有有效用户-企业匹配项,按 `lrrq DESC` 排序;只填一个时仅按该字段过滤。
|
||||
`key` 为空字符串或 null → 返回空结果;`key` 非空 → 对 `dlzh` 与 `qymc` 做 OR 模糊匹配。
|
||||
|
||||
### 3.2 响应
|
||||
|
||||
@ -110,17 +109,21 @@ Controller#listUserByQy
|
||||
JOIN txw_mhzc_yhqygxb g ON g.yh_uuid = y.yh_uuid
|
||||
JOIN txw_mhzc_qyxxb q ON q.qyuuid = g.qyuuid
|
||||
WHERE y.yxbz = 'Y' AND y.sdbz = 'N'
|
||||
<if test="reqVO.dlzh != null and reqVO.dlzh != ''">
|
||||
AND y.dlzh LIKE CONCAT('%', #{reqVO.dlzh}, '%')
|
||||
</if>
|
||||
<if test="reqVO.qymc != null and reqVO.qymc != ''">
|
||||
AND q.qymc LIKE CONCAT('%', #{reqVO.qymc}, '%')
|
||||
</if>
|
||||
<choose>
|
||||
<when test="reqVO.key != null and reqVO.key != ''">
|
||||
AND (y.dlzh LIKE CONCAT('%', #{reqVO.key}, '%')
|
||||
OR q.qymc LIKE CONCAT('%', #{reqVO.key}, '%'))
|
||||
</when>
|
||||
<otherwise>
|
||||
AND 1 = 0
|
||||
</otherwise>
|
||||
</choose>
|
||||
ORDER BY y.lrrq DESC
|
||||
</select>
|
||||
```
|
||||
|
||||
- `LIKE` 参数通过 MyBatis `#{}` 占位符绑定,`%` 由 `CONCAT` 在 SQL 内拼接,不存在 SQL 注入风险
|
||||
- `<choose>` 分支保证 `key` 为空时 SQL 必定返回空(`AND 1=0` 短路),不依赖调用方
|
||||
- 分页由 MyBatis-Plus 的 `PaginationInnerInterceptor` 自动包装(项目已有配置)
|
||||
|
||||
## 6. 代码骨架
|
||||
@ -138,11 +141,8 @@ import lombok.Data;
|
||||
@Data
|
||||
public class UserQyReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "登录账号(模糊匹配,可空)")
|
||||
private String dlzh;
|
||||
|
||||
@Schema(description = "企业名称(模糊匹配,可空)")
|
||||
private String qymc;
|
||||
@Schema(description = "关键字,对登录账号或企业名称做模糊匹配(必填,为空时返回空结果)")
|
||||
private String key;
|
||||
}
|
||||
```
|
||||
|
||||
@ -205,8 +205,8 @@ public CommonResult<Page<UserQyVO>> listUserByQy(@RequestBody UserQyReqVO reqVO)
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| `dlzh` 与 `qymc` 都为空 | 返回所有有效用户-企业项,按 `lrrq DESC` |
|
||||
| 无匹配项 | `Page{records=[], total=0}`,HTTP 200,不抛业务异常 |
|
||||
| `key` 为空字符串或 null | 返回空结果(`Page{records=[], total=0}`,HTTP 200,由 SQL `<otherwise> AND 1=0 </otherwise>` 短路保证) |
|
||||
| `key` 非空但无匹配 | `Page{records=[], total=0}`,HTTP 200,不抛业务异常 |
|
||||
| SQL 异常 | 由全局 `@RestControllerAdvice` 兜底返回 `CommonResult.error` |
|
||||
| 输入含 SQL 通配符(`%`、`_`) | `#{}` 通过预编译参数阻断 SQL 注入(输入中的 `'` 无法闭合 SQL 字符串),因此整体上是**安全的**。但需注意:`#{}` 不会转义 MySQL LIKE 模式元字符(`%`、`_`),输入若含这些字符仍会按 LIKE 通配符匹配。例如输入 `100%`,末位 `%` 会被 MySQL 识别为通配符,等价于 `LIKE '%100<任意内容>%'`。对本接口使用场景(按名称/账号搜索)影响极小,但若将来需要严格字面量匹配,可在 SQL 内对参数做 `REPLACE(..., '%', '\\%')` + 显式 `ESCAPE '\\'`,或调用方自行过滤通配符。 |
|
||||
|
||||
@ -214,10 +214,10 @@ public CommonResult<Page<UserQyVO>> listUserByQy(@RequestBody UserQyReqVO reqVO)
|
||||
|
||||
与现有项目风格一致,以手动验证为主:
|
||||
|
||||
1. **空入参**:`{dlzh:"",qymc:"",pageNo:1,pageSize:10}` → 返回所有有效用户-企业项
|
||||
2. **只按 dlzh**:匹配 dlzh 含子串的所有项
|
||||
3. **只按 qymc**:匹配 qymc 含子串的所有项
|
||||
4. **同时填两个**:AND 关系
|
||||
1. **`key` 为空**:`{key:"",pageNo:1,pageSize:10}` → 返回空结果(`records=[]`、`total=0`)
|
||||
2. **`key` 命中 dlzh**:仅 `dlzh` 含子串的项返回
|
||||
3. **`key` 命中 qymc**:仅 `qymc` 含子串的项返回
|
||||
4. **`key` 同时命中 dlzh 与 qymc**:OR 关系,命中任一即返回
|
||||
5. **多企业用户**:同一 dlzh 出现多条,每条对应一个 qymc
|
||||
6. **过滤被锁定用户**:`sdbz='Y'` 的用户不出现在结果中
|
||||
7. **过滤无效用户**:`yxbz='N'` 的用户不出现在结果中
|
||||
|
||||
@ -8,9 +8,6 @@ import lombok.Data;
|
||||
@Data
|
||||
public class UserQyReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "登录账号(模糊匹配,可空)")
|
||||
private String dlzh;
|
||||
|
||||
@Schema(description = "企业名称(模糊匹配,可空)")
|
||||
private String qymc;
|
||||
@Schema(description = "关键字,对登录账号或企业名称做模糊匹配(必填,为空时返回空结果)")
|
||||
private String key;
|
||||
}
|
||||
|
||||
@ -48,12 +48,15 @@
|
||||
JOIN txw_mhzc_yhqygxb g ON g.yh_uuid = y.yh_uuid
|
||||
JOIN txw_mhzc_qyxxb q ON q.qyuuid = g.qyuuid
|
||||
WHERE y.yxbz = 'Y' AND y.sdbz = 'N'
|
||||
<if test="reqVO.dlzh != null and reqVO.dlzh != ''">
|
||||
AND y.dlzh LIKE CONCAT('%', #{reqVO.dlzh}, '%')
|
||||
</if>
|
||||
<if test="reqVO.qymc != null and reqVO.qymc != ''">
|
||||
AND q.qymc LIKE CONCAT('%', #{reqVO.qymc}, '%')
|
||||
</if>
|
||||
<choose>
|
||||
<when test="reqVO.key != null and reqVO.key != ''">
|
||||
AND (y.dlzh LIKE CONCAT('%', #{reqVO.key}, '%')
|
||||
OR q.qymc LIKE CONCAT('%', #{reqVO.key}, '%'))
|
||||
</when>
|
||||
<otherwise>
|
||||
AND 1 = 0
|
||||
</otherwise>
|
||||
</choose>
|
||||
ORDER BY y.lrrq DESC
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@ -1 +1 @@
|
||||
{"dlzh":"","qymc":"上海链坤数字科技有限公司","pageNo":1,"pageSize":10}
|
||||
{"key":"上海","pageNo":1,"pageSize":10}
|
||||
Loading…
Reference in New Issue
Block a user