Compare commits

..

No commits in common. "5262a80f5b1eb96d3c5fce748a523b392bf64298" and "94d5a3b486812c979e3482cfc20b4b49d0c5f9bb" have entirely different histories.

10 changed files with 54 additions and 199 deletions

View File

@ -8,30 +8,6 @@
**Pure-admin文档**https://pure-admin.github.io/pure-admin-doc **Pure-admin文档**https://pure-admin.github.io/pure-admin-doc
## 视频和地址
**介绍视频视频**
[环境搭建](https://www.bilibili.com/video/BV17odHY6E3S/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
[运行项目](https://www.bilibili.com/video/BV1qodHYzErA/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
[前端部署](https://www.bilibili.com/video/BV1BddHYgEPq/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
[后端部署](https://www.bilibili.com/video/BV1BddHYgEFt/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d42b5b664efb958be39eef8ee1196a7e)
[Bunny v0.0.1 代码生成器](https://www.bilibili.com/video/BV1qddHYgErv/?spm_id_from=333.1387.homepage.video_card.click)
**Github地址**
- 权限后端https://github.com/BunnyMaster/bunny-admin-server
- 权限前端https://github.com/BunnyMaster/bunny-admin-web
- 代码生成器前端https://github.com/BunnyMaster/generator-code-web
- 代码生成器后端https://github.com/BunnyMaster/generator-code-server
**`Gitee`地址**
- 权限后端https://gitee.com/BunnyBoss/bunny-admin-server
- 权限前端https://gitee.com/BunnyBoss/bunny-admin-web
- 代码生成器前端https://gitee.com/BunnyBoss/generator-code-web
- 代码生成器后端https://gitee.com/BunnyBoss/generator-code-server
# 项目预览 # 项目预览
**线上地址** **线上地址**
@ -48,6 +24,20 @@
> >
> ![image-20250108225915189](http://129.211.31.58:9000/docs/image-20250108225915189.png) > ![image-20250108225915189](http://129.211.31.58:9000/docs/image-20250108225915189.png)
**打包视频**
https://www.bilibili.com/video/BV1AYm8YSEKY/
**Github地址**
- [前端地址](https://github.com/BunnyMaster/bunny-admin-web.git)
- [后端地址](https://github.com/BunnyMaster/bunny-admin-server)
**`Gitee`地址**
- [前端地址](https://gitee.com/BunnyBoss/bunny-admin-web)
- [后端地址](https://gitee.com/BunnyBoss/bunny-admin-server)
## 环境搭建 ## 环境搭建
### 安装docker内容 ### 安装docker内容
@ -352,8 +342,8 @@ swagger接口地址http://localhost:7070/swagger-ui/index.html
3. 可以点击已读和全部进行筛选消息 3. 可以点击已读和全部进行筛选消息
4. 可以根据标题进行搜搜 3. 可以根据标题进行搜搜
5. 包含分页 4. 包含分页
#### 实现思路 #### 实现思路

View File

@ -19,6 +19,7 @@
<module>common</module> <module>common</module>
<module>dao</module> <module>dao</module>
<module>service</module> <module>service</module>
<module>common/generator-code</module>
</modules> </modules>
<properties> <properties>

View File

@ -165,5 +165,4 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -15,7 +15,6 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -47,7 +46,7 @@ public class I18nController {
@Operation(summary = "获取管理多语言列", description = "获取管理多语言列") @Operation(summary = "获取管理多语言列", description = "获取管理多语言列")
@GetMapping("getI18nList/{page}/{limit}") @GetMapping("getI18nList/{page}/{limit}")
public Result<PageResult<I18nVo>> getI18nList( public Mono<Result<PageResult<I18nVo>>> getI18nList(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@PathVariable("page") Integer page, @PathVariable("page") Integer page,
@Parameter(name = "limit", description = "每页记录数", required = true) @Parameter(name = "limit", description = "每页记录数", required = true)
@ -55,33 +54,27 @@ public class I18nController {
I18nDto dto) { I18nDto dto) {
Page<I18n> pageParams = new Page<>(page, limit); Page<I18n> pageParams = new Page<>(page, limit);
PageResult<I18nVo> vo = i18nService.getI18nList(pageParams, dto); PageResult<I18nVo> vo = i18nService.getI18nList(pageParams, dto);
return Result.success(vo); return Mono.just(Result.success(vo));
}
@Operation(summary = "下载多语言配置", description = "下载多语言配置")
@GetMapping("downloadI18n")
public ResponseEntity<byte[]> downloadI18n() {
return i18nService.downloadI18n();
} }
@Operation(summary = "添加多语言", description = "添加多语言") @Operation(summary = "添加多语言", description = "添加多语言")
@PostMapping("addI18n") @PostMapping("addI18n")
public Result<Object> addI18n(@Valid @RequestBody I18nAddDto dto) { public Mono<Result<String>> addI18n(@Valid @RequestBody I18nAddDto dto) {
i18nService.addI18n(dto); i18nService.addI18n(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
} }
@Operation(summary = "更新多语言", description = "更新多语言") @Operation(summary = "更新多语言", description = "更新多语言")
@PutMapping("updateI18n") @PutMapping("updateI18n")
public Result<Object> updateI18n(@Valid @RequestBody I18nUpdateDto dto) { public Mono<Result<String>> updateI18n(@Valid @RequestBody I18nUpdateDto dto) {
i18nService.updateI18n(dto); i18nService.updateI18n(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
} }
@Operation(summary = "删除多语言", description = "删除多语言") @Operation(summary = "删除多语言", description = "删除多语言")
@DeleteMapping("deleteI18n") @DeleteMapping("deleteI18n")
public Result<Object> deleteI18n(@RequestBody List<Long> ids) { public Mono<Result<String>> deleteI18n(@RequestBody List<Long> ids) {
i18nService.deleteI18n(ids); i18nService.deleteI18n(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS));
} }
} }

View File

@ -12,6 +12,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import java.util.List; import java.util.List;
@ -33,29 +34,29 @@ public class I18nTypeController {
@Operation(summary = "获取多语言类型", description = "获取多语言类型") @Operation(summary = "获取多语言类型", description = "获取多语言类型")
@GetMapping("/noAuth/getI18nTypeList") @GetMapping("/noAuth/getI18nTypeList")
public Result<List<I18nTypeVo>> getI18nTypeList(I18nTypeDto dto) { public Mono<Result<List<I18nTypeVo>>> getI18nTypeList(I18nTypeDto dto) {
List<I18nTypeVo> voList = i18nTypeService.getI18nTypeList(dto); List<I18nTypeVo> voList = i18nTypeService.getI18nTypeList(dto);
return Result.success(voList); return Mono.just(Result.success(voList));
} }
@Operation(summary = "添加多语言类型", description = "添加多语言类型") @Operation(summary = "添加多语言类型", description = "添加多语言类型")
@PostMapping("addI18nType") @PostMapping("addI18nType")
public Result<Object> addI18nType(@Valid @RequestBody I18nTypeAddDto dto) { public Mono<Result<String>> addI18nType(@Valid @RequestBody I18nTypeAddDto dto) {
i18nTypeService.addI18nType(dto); i18nTypeService.addI18nType(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
} }
@Operation(summary = "更新多语言类型", description = "更新多语言类型") @Operation(summary = "更新多语言类型", description = "更新多语言类型")
@PutMapping("updateI18nType") @PutMapping("updateI18nType")
public Result<Object> updateI18nType(@Valid @RequestBody I18nTypeUpdateDto dto) { public Mono<Result<String>> updateI18nType(@Valid @RequestBody I18nTypeUpdateDto dto) {
i18nTypeService.updateI18nType(dto); i18nTypeService.updateI18nType(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
} }
@Operation(summary = "删除多语言类型", description = "删除多语言类型") @Operation(summary = "删除多语言类型", description = "删除多语言类型")
@DeleteMapping("deleteI18nType") @DeleteMapping("deleteI18nType")
public Result<Object> deleteI18nType(@RequestBody List<Long> ids) { public Mono<Result<String>> deleteI18nType(@RequestBody List<Long> ids) {
i18nTypeService.deleteI18nType(ids); i18nTypeService.deleteI18nType(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS));
} }
} }

View File

@ -9,7 +9,6 @@ import cn.bunny.dao.vo.result.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -58,11 +57,4 @@ public interface I18nService extends IService<I18n> {
* @param ids 删除id列表 * @param ids 删除id列表
*/ */
void deleteI18n(List<Long> ids); void deleteI18n(List<Long> ids);
/**
* 下载多语言配置
*
* @return 文件内容
*/
ResponseEntity<byte[]> downloadI18n();
} }

View File

@ -12,31 +12,23 @@ import cn.bunny.services.exception.AuthCustomerException;
import cn.bunny.services.mapper.configuration.I18nMapper; import cn.bunny.services.mapper.configuration.I18nMapper;
import cn.bunny.services.mapper.configuration.I18nTypeMapper; import cn.bunny.services.mapper.configuration.I18nTypeMapper;
import cn.bunny.services.service.configuration.I18nService; import cn.bunny.services.service.configuration.I18nService;
import cn.bunny.services.utils.system.I18nUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.zip.ZipEntry; import java.util.stream.Collectors;
import java.util.zip.ZipOutputStream;
/** /**
* <p> * <p>
@ -50,11 +42,8 @@ import java.util.zip.ZipOutputStream;
@Transactional @Transactional
public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I18nService { public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I18nService {
private final I18nTypeMapper i18nTypeMapper; @Autowired
private I18nTypeMapper i18nTypeMapper;
public I18nServiceImpl(I18nTypeMapper i18nTypeMapper) {
this.i18nTypeMapper = i18nTypeMapper;
}
/** /**
* * 获取多语言内容 * * 获取多语言内容
@ -68,13 +57,18 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
I18nType i18nType = i18nTypeMapper.selectOne(Wrappers.<I18nType>lambdaQuery().eq(I18nType::getIsDefault, true)); I18nType i18nType = i18nTypeMapper.selectOne(Wrappers.<I18nType>lambdaQuery().eq(I18nType::getIsDefault, true));
List<I18n> i18nList = list(); List<I18n> i18nList = list();
HashMap<String, Object> hashMap = I18nUtil.getMap(i18nList); // 整理集合
hashMap.put("local", Objects.requireNonNull(i18nType.getTypeName(), "zh")); Map<String, Map<String, String>> map = i18nList.stream()
.collect(Collectors.groupingBy(
I18n::getTypeName,
Collectors.toMap(I18n::getKeyName, I18n::getTranslation)));
// 返回集合
HashMap<String, Object> hashMap = new HashMap<>(map);
hashMap.put("local", Objects.requireNonNull(i18nType.getTypeName(), "zh"));
return hashMap; return hashMap;
} }
/** /**
* * 获取管理多语言列表 * * 获取管理多语言列表
* *
@ -146,47 +140,4 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
baseMapper.deleteBatchIdsWithPhysics(ids); baseMapper.deleteBatchIdsWithPhysics(ids);
} }
/**
* 下载多语言配置
*
* @return 文件内容
*/
@Override
public ResponseEntity<byte[]> downloadI18n() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
// 查找默认语言内容
List<I18n> i18nList = list();
HashMap<String, Object> hashMap = I18nUtil.getMap(i18nList);
hashMap.forEach((k, v) -> {
try {
ZipEntry zipEntry = new ZipEntry(k + ".json");
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(JSON.toJSONString(v).getBytes(StandardCharsets.UTF_8));
zipOutputStream.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
try {
zipOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=i18n.zip");
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
return new ResponseEntity<>(byteArrayInputStream.readAllBytes(), headers, HttpStatus.OK);
}
} }

View File

@ -1,23 +0,0 @@
package cn.bunny.services.utils.system;
import cn.bunny.dao.entity.i18n.I18n;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class I18nUtil {
@NotNull
public static HashMap<String, Object> getMap(List<I18n> i18nList) {
// 整理集合
Map<String, Map<String, String>> map = i18nList.stream()
.collect(Collectors.groupingBy(
I18n::getTypeName,
Collectors.toMap(I18n::getKeyName, I18n::getTranslation)));
// 返回集合
return new HashMap<>(map);
}
}

View File

@ -19,20 +19,20 @@ logging:
bunny: bunny:
master: master:
host: 192.168.3.137 host: localhost
port: 3306 port: 3306
database: auth_admin database: auth_admin
username: root username: root
password: "123456" password: "123456"
redis: redis:
host: 192.168.3.137 host: localhost
port: 6379 port: 6379
database: 0 database: 0
password: "123456" password: "123456"
minio: minio:
endpointUrl: "http://192.168.3.137:9000" # 连接地址 endpointUrl: "http://localhost:9000" # 连接地址
accessKey: bunny # 用户名 accessKey: bunny # 用户名
secretKey: "12345678" # 登录密码 secretKey: "12345678" # 登录密码
bucket-name: auth-admin # 指定哪个桶 bucket-name: auth-admin # 指定哪个桶

View File

@ -1,49 +0,0 @@
package cn.bunny.services.service.configuration.impl;
import cn.bunny.dao.entity.i18n.I18n;
import cn.bunny.services.mapper.configuration.I18nMapper;
import cn.bunny.services.utils.system.I18nUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@SpringBootTest
class I18nServiceImplTest extends ServiceImpl<I18nMapper, I18n> {
@Test
void downloadI18n() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
// 查找默认语言内容
List<I18n> i18nList = list();
HashMap<String, Object> hashMap = I18nUtil.getMap(i18nList);
hashMap.forEach((k, v) -> {
try {
ZipEntry zipEntry = new ZipEntry(k + ".json");
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(JSON.toJSONString(v).getBytes(StandardCharsets.UTF_8));
zipOutputStream.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
try {
zipOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}