Compare commits

...

3 Commits

Author SHA1 Message Date
gxwebsoft e7a12d8828 fix(system): 修复素材管理搜索中的列名错误
- 修正 FileRecordMapper.xml 中关键词搜索部分,将 b.name 和 b.comments 改为正确字段
- 搜索范围扩展至文件名、路径、注释及用户的用户名、昵称和真实姓名
- 添加关键词数字校验,避免非数字字符串误匹配 create_user_id
- 防止因跨 Mapper 复制导致的表别名错误及字段不存在的问题
2026-09-03 11:15:01 +08:00
gxwebsoft c88b41fd46 fix(WxLoginController): 修正 getOrderQRCodeUnlimited 接口 scene 参数逻辑
- 调整 scene 参数优先级为:显式 scene > 自定义页面使用原始 orderNo > 兼容原订单核销 scene=orderNo=xxx
- 当传入页面参数时,scene 直接使用原始 orderNo,满足小程序端 options.scene 读取需求
- page 参数无传入时默认设置为 package/admin/order-scan,保持兼容旧版订单核销页面
- 保证原有订单核销逻辑和接口调用行为向下兼容无影响
2026-09-01 12:06:45 +08:00
gxwebsoft f751d17771 feat(system): 优化微信小程序码获取接口,直接返回图片字节
- 修改getOrderQRCodeUnlimited接口,支持直接返回图片字节流
- 移除保存二维码图片到服务器文件的逻辑
- 在未登录时,通过响应码401返回错误提示
- 设置响应内容类型为image/png,禁用缓存,直接输出二维码图片数据
- 简化接口实现,提升性能与用户体验
2026-08-31 18:20:32 +08:00
4 changed files with 56 additions and 24 deletions
+7
View File
@@ -0,0 +1,7 @@
# 2026-09-01 工作记录
## 修复 getOrderQRCodeUnlimited scene 参数 bug
- 文件:`src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java`
- 问题:后台管理端调用 `/getOrderQRCodeUnlimited/e9?page=pages/event/detail/index` 时,因未传 `scene`,回退逻辑生成 `scene=orderNo=e9`,而 `pages/event/detail/index` 页面期望 `scene=e9`(直接读 options.scene)。
- 修复:scene 取值优先级改为 `显式 scene > 自定义页面用原始 orderNo > 兼容原订单核销(orderNo=xxx)`page 无参时默认 `package/admin/order-scan`
- 兼容性:原订单核销用法(不带参数)行为不变;自定义页面默认用原始 orderNo;需 `orderNo=` 格式可显式传 `?scene=orderNo=e9`
+10
View File
@@ -0,0 +1,10 @@
# 2026-09-03
## 修复:素材管理搜索报 Unknown column 'b.name'
- 文件:`src/main/java/com/gxwebsoft/common/system/mapper/xml/FileRecordMapper.xml`
- 根因:`selectSql``keywords` 模糊搜索块(2024-11-25 提交 cf4f010 引入,疑似从 UserVerifyMapper 复制过来未改别名)写成了 `b.name` / `b.comments`
该块中 `a` = sys_file_record`b` = sys_usersys_user **没有** `name` 字段(只有 username / nickname / real_name / phone),故 MySQL 报 `Unknown column 'b.name' in 'where clause'`
- 修复:关键词改为搜索文件侧字段 `a.name` / `a.path` / `a.comments`,加上传者 `b.username` / `b.nickname` / `b.real_name`
`a.create_user_id = #{param.keywords}``<if test="param.keywords.matches('[0-9]+')">` 包住,避免非数字关键词被 MySQL 隐式转成 0。
- 教训:跨 mapper 复制动态 SQL 片段时,务必核对表别名与目标表字段(sys_user 无 name 列)。
@@ -35,7 +35,9 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -965,19 +967,31 @@ public class WxLoginController extends BaseController {
return fail("获取失败", null);
}
@Operation(summary = "获取微信小程序码-数量极多的业务场景(支持自定义页面与场景值)")
@Operation(summary = "获取微信小程序码-数量极多的业务场景(直接返回图片字节,支持自定义页面与场景值)")
@GetMapping("/getOrderQRCodeUnlimited/{orderNo}")
public ApiResult<?> getOrderQRCodeUnlimited(@PathVariable("orderNo") String orderNo,
@RequestParam(required = false) String page,
@RequestParam(required = false) String scene) {
public void getOrderQRCodeUnlimited(@PathVariable("orderNo") String orderNo,
@RequestParam(required = false) String page,
@RequestParam(required = false) String scene,
HttpServletResponse response) throws IOException {
final User loginUser = getLoginUser();
if(loginUser == null){
return fail("请先登录");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "请先登录");
return;
}
String apiUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + getAccessToken(loginUser.getTenantId());
final HashMap<String, Object> map = new HashMap<>();
// scene 优先用入参,否则回退兼容原订单核销逻辑:orderNo=xxx
map.put("scene", StrUtil.isNotBlank(scene) ? scene : "orderNo=".concat(orderNo));
// scene 优先级:显式 scene > 自定义页面用原始 orderNo > 兼容原订单核销(orderNo=xxx)
String sceneValue;
if (StrUtil.isNotBlank(scene)) {
sceneValue = scene;
} else if (StrUtil.isNotBlank(page)) {
// 自定义页面场景:小程序端通过 options.scene 直接读取业务值(如活动/订单号)
sceneValue = orderNo;
} else {
// 兼容原订单核销场景:scene=orderNo=xxx,默认跳转 package/admin/order-scan
sceneValue = "orderNo=".concat(orderNo);
}
map.put("scene", sceneValue);
// page 优先用入参,否则回退兼容原订单核销页面
map.put("page", StrUtil.isNotBlank(page) ? page : "package/admin/order-scan");
map.put("env_version", "trial");
@@ -985,17 +999,12 @@ public class WxLoginController extends BaseController {
byte[] qrCode = HttpRequest.post(apiUrl)
.body(JSON.toJSONString(map))
.execute().bodyBytes();
System.out.println("qrCode = " + qrCode);
// 保存的文件名称
final String fileName = CommonUtil.randomUUID8().concat(".png");
// 保存路径
String filePath = getUploadDir().concat("qrcode/") + fileName;
File file = FileUtil.writeBytes(qrCode, filePath);
if (file != null) {
return success(config.getFileServer().concat("/qrcode/").concat(fileName));
}
return fail("获取失败", null);
// 直接将小程序码图片字节写回响应,不依赖 file.websoft.top 文件服务器
response.setContentType("image/png");
response.setHeader("Cache-Control", "no-cache");
response.getOutputStream().write(qrCode);
response.getOutputStream().flush();
}
@@ -59,13 +59,19 @@
<if test="param.contentType != null">
AND a.content_type LIKE CONCAT('%', #{param.contentType}, '%')
</if>
<if test="param.keywords != null">
AND (
a.create_user_id = #{param.keywords}
OR b.name LIKE CONCAT('%', #{param.keywords}, '%')
OR b.comments LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
<if test="param.keywords != null and param.keywords != ''">
AND (
a.`name` LIKE CONCAT('%', #{param.keywords}, '%')
OR a.path LIKE CONCAT('%', #{param.keywords}, '%')
OR a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.username LIKE CONCAT('%', #{param.keywords}, '%')
OR b.nickname LIKE CONCAT('%', #{param.keywords}, '%')
OR b.real_name LIKE CONCAT('%', #{param.keywords}, '%')
<if test="param.keywords.matches('[0-9]+')">
OR a.create_user_id = #{param.keywords}
</if>
)
</if>
</where>
</sql>