From c79dc93ba449e26db810d067f28e19a7acc3c5be Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Fri, 18 Apr 2025 18:10:35 +0800 Subject: [PATCH] =?UTF-8?q?2025.4.17=20=E4=BF=AE=E6=94=B9filebrowser?= =?UTF-8?q?=E7=9A=84bug=20=E5=A2=9E=E5=8A=A0=E5=A5=97=E9=A4=90=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sky/constant/MessageConstant.java | 1 + .../java/com/sky/context/BaseContext.java | 2 - .../java/com/sky/utils/FileBrowserUtil.java | 57 +++++++------ .../controller/admin/CommonController.java | 8 +- .../controller/admin/SetmealController.java | 12 +-- .../sky/handler/GlobalExceptionHandler.java | 5 ++ .../com/sky/mapper/SetmealDishMapper.java | 21 +++-- .../java/com/sky/mapper/SetmealMapper.java | 39 ++++++++- .../java/com/sky/service/SetmealService.java | 4 +- .../sky/service/impl/SetmealServiceImpl.java | 81 ++++++++++++++----- sky-server/src/main/resources/application.yml | 2 +- .../resources/mapper/SetmealDishMapper.xml | 7 +- .../main/resources/mapper/SetmealMapper.xml | 24 ++++-- 13 files changed, 185 insertions(+), 78 deletions(-) diff --git a/sky-common/src/main/java/com/sky/constant/MessageConstant.java b/sky-common/src/main/java/com/sky/constant/MessageConstant.java index 50d5af0..44cb0e1 100644 --- a/sky-common/src/main/java/com/sky/constant/MessageConstant.java +++ b/sky-common/src/main/java/com/sky/constant/MessageConstant.java @@ -25,4 +25,5 @@ public class MessageConstant { public static final String ORDER_STATUS_ERROR = "订单状态错误"; public static final String ORDER_NOT_FOUND = "订单不存在"; public static final String ALREADY_EXISTS = "已存在"; + public static final String SYSTEM_ERROR = "系统发生未知异常,正在努力修复中!"; } diff --git a/sky-common/src/main/java/com/sky/context/BaseContext.java b/sky-common/src/main/java/com/sky/context/BaseContext.java index c7ba505..658a71e 100644 --- a/sky-common/src/main/java/com/sky/context/BaseContext.java +++ b/sky-common/src/main/java/com/sky/context/BaseContext.java @@ -1,7 +1,5 @@ package com.sky.context; -import lombok.Data; - public class BaseContext { public static ThreadLocal threadLocal = new ThreadLocal<>(); diff --git a/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java b/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java index ab578db..92c6a0a 100644 --- a/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java +++ b/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java @@ -1,5 +1,4 @@ package com.sky.utils; - import com.alibaba.fastjson.JSONObject; import lombok.AllArgsConstructor; import lombok.Data; @@ -7,17 +6,16 @@ import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; +import java.net.URLConnection; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.UUID; @Slf4j @AllArgsConstructor @@ -67,7 +65,8 @@ public class FileBrowserUtil { // 返回原始返回值(假设就是 JWT token 字符串) return body; } else { - throw new IOException("Login failed, HTTP status code: " + statusCode); + log.error("Login failed, HTTP status code: " + statusCode); + return ""; } } } @@ -80,42 +79,42 @@ public class FileBrowserUtil { * -H "X-Auth: $TOKEN" \ * -F "data=@/path/to/local/photo.jpg" //photo.jpg 以 multipart/form-data 的格式上传 */ - public String upload(byte[] fileBytes, String objectName) throws IOException { - // 1.获取唯一文件名 - // 2. 构造远程路径:固定到 userfiles 目录 - String remotePath = "userfiles/" + objectName; - - // 3. 获取登录令牌 + public String uploadAndGetUrl(byte[] fileBytes, String fileName) throws IOException { + // 1. 登录拿 token String token = login(); - // 4. URL 编码(保留斜杠) + // 2. 确定远端存储路径和编码(保留斜杠) + String remotePath = "store/" + fileName; String encodedPath = URLEncoder.encode(remotePath, StandardCharsets.UTF_8.toString()) .replace("%2F", "/"); - String url = domain + "/api/resources/" + encodedPath + "?override=true"; - // 5. 构建并发送 multipart/form-data 请求 + // 3. 根据文件名猜 MIME 类型,fallback 到 application/octet-stream + String mimeType = URLConnection.guessContentTypeFromName(fileName); + if (mimeType == null) { + mimeType = "application/octet-stream"; + } + + // 4. 构造上传 URL + String uploadUrl = domain + "/api/resources/" + encodedPath + "?override=true"; + + // 5. 执行 Multipart upload try (CloseableHttpClient client = HttpClients.createDefault()) { - HttpPost post = new HttpPost(url); + HttpPost post = new HttpPost(uploadUrl); post.setHeader("X-Auth", token); - - HttpEntity multipart = MultipartEntityBuilder.create() - .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - // name="files",filename 用新生成的 objectName - .addBinaryBody("files", fileBytes, ContentType.APPLICATION_OCTET_STREAM, objectName) - .build(); - - post.setEntity(multipart); - + post.setEntity(new ByteArrayEntity(fileBytes, ContentType.create(mimeType))); try (CloseableHttpResponse resp = client.execute(post)) { int status = resp.getStatusLine().getStatusCode(); String body = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8); - if (status >= 200 && status < 300) { - log.info("上传成功 → {}", remotePath); - return body; - } else { - throw new IOException("上传失败,HTTP " + status + ",响应:" + body); + if (status < 200 || status >= 300) { + log.error("文件上传失败: HTTP {},{}", status, body); + return ""; } } } + + // 6. 拼接 raw 下载链接并返回 + String downloadUrl = domain + "/api/raw/" + encodedPath; + log.info("文件下载链接:{}", downloadUrl); + return downloadUrl; } } diff --git a/sky-server/src/main/java/com/sky/controller/admin/CommonController.java b/sky-server/src/main/java/com/sky/controller/admin/CommonController.java index b10a77b..7d96b5e 100644 --- a/sky-server/src/main/java/com/sky/controller/admin/CommonController.java +++ b/sky-server/src/main/java/com/sky/controller/admin/CommonController.java @@ -3,6 +3,7 @@ package com.sky.controller.admin; import com.sky.constant.MessageConstant; import com.sky.result.Result; import com.sky.utils.AliOssUtil; +import com.sky.utils.FileBrowserUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.io.IOException; import java.util.UUID; @@ -26,7 +28,8 @@ public class CommonController { @Autowired private AliOssUtil aliOssUtil; - + @Autowired + private FileBrowserUtil fileBrowserUtil; /** * 文件上传 * @param file @@ -46,7 +49,8 @@ public class CommonController { String objectName = UUID.randomUUID().toString() + extension; //文件的访问地址 - String filePath = aliOssUtil.upload(file.getBytes(), objectName); +// String filePath = aliOssUtil.upload(file.getBytes(), objectName); + String filePath = fileBrowserUtil.uploadAndGetUrl(file.getBytes(),objectName); return Result.success(filePath); } catch (IOException e) { log.error("文件上传失败:{}", e); diff --git a/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java b/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java index a4a74cf..8f7aa18 100644 --- a/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java +++ b/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java @@ -13,6 +13,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController("adminSetmealController") @Slf4j @Api("套餐相关接口") @@ -24,9 +26,8 @@ public class SetmealController { @PostMapping @ApiOperation("新增套餐") @CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")//key: setmealCache::100 - public Result addSetmeal(@RequestBody SetmealDTO setmealDTO){ - log.info("新增套餐"); - setmealService.addSetmeal(setmealDTO); + public Result save(@RequestBody SetmealDTO setmealDTO){ + setmealService.saveWithDish(setmealDTO); return Result.success(); } @GetMapping("/page") @@ -36,10 +37,9 @@ public class SetmealController { return Result.success(pageResult); } @DeleteMapping - @ApiOperation("删除套餐") + @ApiOperation("批量删除套餐") @CacheEvict(cacheNames = "setmealCache",allEntries = true) - public Result deleteByIds(@RequestParam Long[] ids){ - log.info("删除套餐"); + public Result delete(@RequestParam List ids){ setmealService.deleteBatch(ids); return Result.success(); } diff --git a/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java b/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java index 6cbe2da..4a44c9f 100644 --- a/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java +++ b/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java @@ -40,4 +40,9 @@ public class GlobalExceptionHandler { return Result.error(MessageConstant.UNKNOWN_ERROR); } } + @ExceptionHandler(Exception.class) + public Result handleAll(Exception ex) { + log.error("未处理的异常:", ex); + return Result.error(MessageConstant.SYSTEM_ERROR); + } } diff --git a/sky-server/src/main/java/com/sky/mapper/SetmealDishMapper.java b/sky-server/src/main/java/com/sky/mapper/SetmealDishMapper.java index 6942a60..b1e22cd 100644 --- a/sky-server/src/main/java/com/sky/mapper/SetmealDishMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/SetmealDishMapper.java @@ -9,13 +9,24 @@ import java.util.List; @Mapper public interface SetmealDishMapper { -// @Select("select setmeal_id from setmeal_dish where dish_id=#{id}") -// List queryByDishId(Long id); + /** + * 批量保存套餐和菜品的关联关系 + */ + void insertBatch(List setmealDishes); - void add(SetmealDish setmealDish); - @Delete("delete from setmeal_dish where setmeal_id=#{id}") - void deleteByDishId(Long id); + /** + * 根据套餐id删除套餐和菜品的关联关系 + * + * @param setmealId + */ + @Delete("delete from setmeal_dish where setmeal_id=#{setmealId}") + void deleteBySetmealId(Long setmealId); + /** + * 根据套餐id查询 + * + * @param setmealId + */ @Select("select * from setmeal_dish where setmeal_id = #{setmealId}") List getBySetmealId(Long setmealId); diff --git a/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java b/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java index 3419727..20760ae 100644 --- a/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java @@ -1,5 +1,6 @@ package com.sky.mapper; +import com.github.pagehelper.Page; import com.sky.annotation.AutoFill; import com.sky.dto.SetmealPageQueryDTO; import com.sky.entity.Setmeal; @@ -14,24 +15,58 @@ import java.util.List; @Mapper public interface SetmealMapper { + /** + * 新增套餐 + * + * @param setmeal + */ @AutoFill(OperationType.INSERT) void insert(Setmeal setmeal); - List queryByCond(SetmealPageQueryDTO setmealPageQueryDTO); + /** + * 分页查询 + * @param setmealPageQueryDTO + * @return + */ + Page pageQuery(SetmealPageQueryDTO setmealPageQueryDTO); + + /** + * 根据id查询套餐 + * @param id + * @return + */ @Select("select * from setmeal where id=#{id}") Setmeal getById(Long id); + + /** + * 根据id删除套餐 + * @param id + */ @Delete("delete from setmeal where id=#{id};") void deleteById(Long id); + + /** + * 修改套餐 + * + * @param setmeal + */ @AutoFill(OperationType.UPDATE) void update(Setmeal setmeal); + /** * 动态条件查询套餐 * @param setmeal * @return */ List list(Setmeal setmeal); + + /** + * 根据套餐id查询菜品选项 + * @param setmealId + * @return + */ @Select("select sd.name, sd.copies, d.image, d.description " + "from setmeal_dish sd left join dish d on sd.dish_id = d.id " + "where sd.setmeal_id = #{setmealId}") - List getDishItemBySetmealId(Long id); + List getDishItemBySetmealId(Long setmealId); } diff --git a/sky-server/src/main/java/com/sky/service/SetmealService.java b/sky-server/src/main/java/com/sky/service/SetmealService.java index 35cc006..ebd6ac7 100644 --- a/sky-server/src/main/java/com/sky/service/SetmealService.java +++ b/sky-server/src/main/java/com/sky/service/SetmealService.java @@ -10,11 +10,11 @@ import com.sky.vo.SetmealVO; import java.util.List; public interface SetmealService { - void addSetmeal(SetmealDTO setmealDTO); + void saveWithDish(SetmealDTO setmealDTO); PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO); - void deleteBatch(Long[] ids); + void deleteBatch(List ids); SetmealVO getByIdWithDish(Long id); diff --git a/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java index 15226d5..f9d7008 100644 --- a/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java +++ b/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java @@ -30,51 +30,78 @@ public class SetmealServiceImpl implements SetmealService { @Autowired private SetmealMapper setmealMapper; @Autowired - private SetmealDishMapper setmeal_dishMapper; + private SetmealDishMapper setmealDishMapper; @Autowired private DishMapper dishMapper; @Override - public void addSetmeal(SetmealDTO setmealDTO) { + /** + * 新增套餐,同时需要保存套餐和菜品的关联关系 + * + * @param setmealDTO + */ + public void saveWithDish(SetmealDTO setmealDTO) { Setmeal setmeal=new Setmeal(); BeanUtils.copyProperties(setmealDTO,setmeal); + + //向套餐表插入数据 setmealMapper.insert(setmeal); + //获取生成的套餐id + Long setmealId = setmeal.getId(); + List setmealDishList =setmealDTO.getSetmealDishes(); for(SetmealDish setmealDish:setmealDishList){ - setmealDish.setSetmealId(setmeal.getId()); - setmeal_dishMapper.add(setmealDish); + setmealDish.setSetmealId(setmealId); } + setmealDishMapper.insertBatch(setmealDishList); } + /** + * 分页查询 + * + * @param setmealPageQueryDTO + * @return + */ @Override public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) { PageHelper.startPage(setmealPageQueryDTO.getPage(),setmealPageQueryDTO.getPageSize()); - List setmealVOList=setmealMapper.queryByCond(setmealPageQueryDTO); - Page p= (Page) setmealVOList; - PageResult pageResult=new PageResult(p.getTotal(),p.getResult()); - return pageResult; + Page page = setmealMapper.pageQuery(setmealPageQueryDTO); + return new PageResult(page.getTotal(),page.getResult()); } + /** + * 批量删除套餐 + * + * @param ids + */ @Override @Transactional - public void deleteBatch(Long[] ids) { - for(Long id:ids){ + public void deleteBatch(List ids) { + ids.forEach(id -> { Setmeal setmeal = setmealMapper.getById(id); - if(StatusConstant.ENABLE == setmeal.getStatus()){ + if (StatusConstant.ENABLE == setmeal.getStatus()) { //起售中的套餐不能删除 throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE); } - else{ - Long setmealId=id; - setmealMapper.deleteById(id); - setmeal_dishMapper.deleteByDishId(id); - } - } + }); + + ids.forEach(setmealId -> { + //删除套餐表中的数据 + setmealMapper.deleteById(setmealId); + //删除套餐菜品关系表中的数据 + setmealDishMapper.deleteBySetmealId(setmealId); + }); } + /** + * 根据id查询套餐和套餐菜品关系 + * + * @param id + * @return + */ @Override public SetmealVO getByIdWithDish(Long id) { Setmeal setmeal = setmealMapper.getById(id); - List setmealDishes = setmeal_dishMapper.getBySetmealId(id); + List setmealDishes = setmealDishMapper.getBySetmealId(id); SetmealVO setmealVO = new SetmealVO(); BeanUtils.copyProperties(setmeal, setmealVO); setmealVO.setSetmealDishes(setmealDishes); @@ -82,7 +109,13 @@ public class SetmealServiceImpl implements SetmealService { return setmealVO; } + /** + * 修改套餐 + * + * @param setmealDTO + */ @Override + @Transactional public void update(SetmealDTO setmealDTO) { Setmeal setmeal = new Setmeal(); BeanUtils.copyProperties(setmealDTO, setmeal); @@ -94,18 +127,22 @@ public class SetmealServiceImpl implements SetmealService { Long setmealId = setmealDTO.getId(); //2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行delete - setmeal_dishMapper.deleteByDishId(setmealId); + setmealDishMapper.deleteBySetmealId(setmealId); List setmealDishes = setmealDTO.getSetmealDishes(); setmealDishes.forEach(setmealDish -> { setmealDish.setSetmealId(setmealId); }); //3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insert - for(SetmealDish setmealDish:setmealDishes){ - setmeal_dishMapper.add(setmealDish); - } + setmealDishMapper.insertBatch(setmealDishes); } + /** + * 套餐起售、停售 + * + * @param status + * @param id + */ @Override public void startOrStop(Integer status, Long id) { //起售套餐时,判断套餐内是否有停售菜品,有停售菜品提示"套餐内包含未启售菜品,无法启售" diff --git a/sky-server/src/main/resources/application.yml b/sky-server/src/main/resources/application.yml index 0486e81..981c99e 100644 --- a/sky-server/src/main/resources/application.yml +++ b/sky-server/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 8085 spring: profiles: diff --git a/sky-server/src/main/resources/mapper/SetmealDishMapper.xml b/sky-server/src/main/resources/mapper/SetmealDishMapper.xml index f5ac6c9..9cb5a17 100644 --- a/sky-server/src/main/resources/mapper/SetmealDishMapper.xml +++ b/sky-server/src/main/resources/mapper/SetmealDishMapper.xml @@ -3,9 +3,12 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > - + insert into setmeal_dish (setmeal_id,dish_id,name,price,copies) - values (#{setmealId},#{dishId},#{name},#{price},#{copies}) + values + + (#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies}) + - select c.*,d.name from setmeal as c left outer join category as d on c.category_id=d.id +