2025.4.17 修改filebrowser的bug 增加套餐的接口

This commit is contained in:
zhangsan 2025-04-18 18:10:35 +08:00
parent 88c32f02b5
commit c79dc93ba4
13 changed files with 185 additions and 78 deletions

View File

@ -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 = "系统发生未知异常,正在努力修复中!";
}

View File

@ -1,7 +1,5 @@
package com.sky.context;
import lombok.Data;
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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<Long> ids){
setmealService.deleteBatch(ids);
return Result.success();
}

View File

@ -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);
}
}

View File

@ -9,13 +9,24 @@ import java.util.List;
@Mapper
public interface SetmealDishMapper {
// @Select("select setmeal_id from setmeal_dish where dish_id=#{id}")
// List<Long> queryByDishId(Long id);
/**
* 批量保存套餐和菜品的关联关系
*/
void insertBatch(List<SetmealDish> 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<SetmealDish> getBySetmealId(Long setmealId);

View File

@ -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<SetmealVO> queryByCond(SetmealPageQueryDTO setmealPageQueryDTO);
/**
* 分页查询
* @param setmealPageQueryDTO
* @return
*/
Page<SetmealVO> 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<Setmeal> 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<DishItemVO> getDishItemBySetmealId(Long id);
List<DishItemVO> getDishItemBySetmealId(Long setmealId);
}

View File

@ -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<Long> ids);
SetmealVO getByIdWithDish(Long id);

View File

@ -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<SetmealDish> 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<SetmealVO> setmealVOList=setmealMapper.queryByCond(setmealPageQueryDTO);
Page<SetmealVO> p= (Page<SetmealVO>) setmealVOList;
PageResult pageResult=new PageResult(p.getTotal(),p.getResult());
return pageResult;
Page<SetmealVO> 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<Long> 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<SetmealDish> setmealDishes = setmeal_dishMapper.getBySetmealId(id);
List<SetmealDish> 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<SetmealDish> 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) {
//起售套餐时判断套餐内是否有停售菜品有停售菜品提示"套餐内包含未启售菜品,无法启售"

View File

@ -1,5 +1,5 @@
server:
port: 8080
port: 8085
spring:
profiles:

View File

@ -3,9 +3,12 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.SetmealDishMapper">
<insert id="add">
<insert id="insertBatch" parameterType="list">
insert into setmeal_dish (setmeal_id,dish_id,name,price,copies)
values (#{setmealId},#{dishId},#{name},#{price},#{copies})
values
<foreach collection="setmealDishes" item="sd" separator=",">
(#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
</foreach>
</insert>
<select id="getSetmealIdsByDishIds" resultType="java.lang.Long">
select setmeal_id from setmeal_dish where dish_id in

View File

@ -21,13 +21,27 @@
</set>
where id=#{id}
</update>
<select id="queryByCond" resultType="com.sky.vo.SetmealVO">
select c.*,d.name from setmeal as c left outer join category as d on c.category_id=d.id
<select id="pageQuery" resultType="com.sky.vo.SetmealVO">
select
s.*,c.name categoryName
from
setmeal s
left join
category c
on
s.category_id = c.id
<where>
<if test="categoryId!=null">and c.category_id=#{categoryId}</if>
<if test="name!=null and name!=''">and c.name like concat('%',#{name},'%')</if>
<if test="status!=null">and c.status=#{status}</if>
<if test="name != null">
and s.name like concat('%',#{name},'%')
</if>
<if test="status != null">
and s.status = #{status}
</if>
<if test="categoryId != null">
and s.category_id = #{categoryId}
</if>
</where>
order by s.create_time desc
</select>
<select id="list" resultType="com.sky.entity.Setmeal">
select * from setmeal