You've already forked FrameTour-BE
Compare commits
46 Commits
b0adf414d0
...
master
Author | SHA1 | Date | |
---|---|---|---|
1059d30c21 | |||
4d53986277 | |||
156c487c0f | |||
38e9763033 | |||
1dc9e16c55 | |||
4f0d1813c9 | |||
d2577f0c0f | |||
2adce97503 | |||
1eb527574b | |||
22dea22fc1 | |||
a425c155d0 | |||
ceaf10977d | |||
a5a7957f9e | |||
ce0cbb1c91 | |||
2274ca7010 | |||
18fd50f5d6 | |||
13ef1d1334 | |||
8b957ee96d | |||
b3df268964 | |||
f54595466a | |||
d7d503212f | |||
52086dbea4 | |||
f084b7a21f | |||
3aa039f0ea | |||
1ca7182979 | |||
78079b242a | |||
fd66448f4d | |||
64c4180e4d | |||
af141161de | |||
0317600910 | |||
eda2c75533 | |||
0ecd9d5e20 | |||
722b8a9e90 | |||
69f4ad11ad | |||
49c313b4a0 | |||
5bac59653b | |||
0dbaf5eaba | |||
d180128edb | |||
bd308f35ae | |||
cb312b1a74 | |||
6862ddbf58 | |||
51ba702d82 | |||
ecc011269c | |||
f84adc8ebe | |||
17d63688c6 | |||
3f5dc41310 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
.idea/
|
.idea/
|
||||||
logs/
|
logs/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
|
.claude
|
123
CLAUDE.md
Normal file
123
CLAUDE.md
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
本文件为 Claude Code (claude.ai/code) 在此代码仓库中工作时提供指导。
|
||||||
|
|
||||||
|
## 构建和开发命令
|
||||||
|
|
||||||
|
### 构建应用程序
|
||||||
|
```bash
|
||||||
|
# 清理构建(默认跳过测试)
|
||||||
|
mvn clean package
|
||||||
|
|
||||||
|
# 清理构建并执行测试
|
||||||
|
mvn clean package -DskipTests=false
|
||||||
|
|
||||||
|
# 运行应用程序
|
||||||
|
mvn spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试命令
|
||||||
|
```bash
|
||||||
|
# 运行特定测试类
|
||||||
|
mvn test -Dtest=FaceCleanerTest
|
||||||
|
|
||||||
|
# 运行特定包的测试
|
||||||
|
mvn test -Dtest="com.ycwl.basic.storage.adapters.*Test"
|
||||||
|
|
||||||
|
# 运行所有测试
|
||||||
|
mvn test -DskipTests=false
|
||||||
|
```
|
||||||
|
|
||||||
|
### 开发环境配置
|
||||||
|
应用程序使用 Spring 配置文件:
|
||||||
|
- 默认激活配置文件:`dev`
|
||||||
|
- 生产环境配置文件:`prod`(启用定时任务)
|
||||||
|
- 配置文件:`application-dev.yml`、`application-prod.yml`
|
||||||
|
|
||||||
|
## 架构概览
|
||||||
|
|
||||||
|
这是一个 Spring Boot 3.3.5 应用程序(Java 21),采用多租户架构,通过不同的 API 端点为不同的客户端类型提供服务。
|
||||||
|
|
||||||
|
### 控制器架构
|
||||||
|
- **移动端 APIs** (`/api/mobile/`):面向移动应用的客户端端点
|
||||||
|
- **PC 端 APIs** (`/api/`):Web 仪表板/管理面板端点
|
||||||
|
- **任务 APIs** (`/task/`):后台工作和渲染任务端点
|
||||||
|
- **外部 APIs**:专用集成(打印机、代理、viid、vpt、wvp)
|
||||||
|
|
||||||
|
### 核心业务模块
|
||||||
|
|
||||||
|
#### 工厂模式实现
|
||||||
|
三个主要工厂类管理第三方集成:
|
||||||
|
|
||||||
|
1. **StorageFactory** (`com.ycwl.basic.storage.StorageFactory`)
|
||||||
|
- 管理:本地存储、AWS S3、阿里云 OSS 存储适配器
|
||||||
|
- 配置节:`storage.configs[]`
|
||||||
|
|
||||||
|
2. **PayFactory** (`com.ycwl.basic.pay.PayFactory`)
|
||||||
|
- 管理:微信支付、聪明支付适配器
|
||||||
|
- 配置节:`pay.configs[]`
|
||||||
|
|
||||||
|
3. **FaceBodyFactory** (`com.ycwl.basic.facebody.FaceBodyFactory`)
|
||||||
|
- 管理:阿里云、百度人脸识别适配器
|
||||||
|
- 配置节:`facebody.configs[]`
|
||||||
|
|
||||||
|
#### 适配器模式
|
||||||
|
每个工厂使用标准化接口:
|
||||||
|
- `IStorageAdapter`:文件操作(上传/下载/删除/ACL)
|
||||||
|
- `IPayAdapter`:支付生命周期(创建/回调/退款)
|
||||||
|
- `IFaceBodyAdapter`:人脸识别操作
|
||||||
|
|
||||||
|
#### 定时任务系统
|
||||||
|
`com.ycwl.basic.task` 包中的后台任务(仅生产环境):
|
||||||
|
- `VideoTaskGenerator`:人脸识别和视频处理
|
||||||
|
- `FaceCleaner`:人脸和存储清理任务
|
||||||
|
- `DynamicTaskGenerator`:带延迟队列的动态任务创建
|
||||||
|
- `ScenicStatsTask`:统计数据聚合
|
||||||
|
|
||||||
|
### 数据库和持久化
|
||||||
|
- **MyBatis Plus**:具有自动 CRUD 操作的 ORM
|
||||||
|
- **MapperScan**:扫描 `com.ycwl.basic.mapper` 及子包
|
||||||
|
- **数据库**:MySQL 配合 HikariCP 连接池
|
||||||
|
- **Redis**:会话管理和缓存
|
||||||
|
|
||||||
|
### 主要库和依赖
|
||||||
|
- Spring Boot 3.3.5 启用 Java 21 虚拟线程
|
||||||
|
- MyBatis Plus 3.5.5 用于数据库操作
|
||||||
|
- JWT (jjwt 0.9.0) 用于身份验证
|
||||||
|
- 微信支付 SDK 用于支付处理
|
||||||
|
- 阿里云 OSS 和 AWS S3 用于文件存储
|
||||||
|
- 阿里云和百度 SDK 用于人脸识别
|
||||||
|
- OpenTelemetry 用于可观测性(开发环境中禁用)
|
||||||
|
|
||||||
|
### 业务逻辑组织
|
||||||
|
- **Service 层**:`service` 包中的业务逻辑实现
|
||||||
|
- **Biz 层**:`biz` 包中的高级业务编排
|
||||||
|
- **Repository 模式**:`repository` 包中的数据访问抽象
|
||||||
|
- **自定义异常**:特定领域的异常处理
|
||||||
|
|
||||||
|
### 配置管理
|
||||||
|
每个模块使用 Spring Boot 自动配置启动器:
|
||||||
|
- 支持多供应商的命名配置
|
||||||
|
- 通过配置进行默认供应商选择
|
||||||
|
- 针对不同环境的特定配置文件
|
||||||
|
|
||||||
|
## 常见开发模式
|
||||||
|
|
||||||
|
### 添加新的存储/支付/人脸识别供应商
|
||||||
|
1. 实现相应接口(`IStorageAdapter`、`IPayAdapter`、`IFaceBodyAdapter`)
|
||||||
|
2. 在相应的类型枚举中添加枚举值
|
||||||
|
3. 更新工厂的 switch 表达式
|
||||||
|
4. 如需要,添加配置类
|
||||||
|
5. 在 application.yml 中更新新供应商配置
|
||||||
|
|
||||||
|
### 身份验证上下文
|
||||||
|
在整个应用程序中使用 `BaseContextHandler.getUserId()` 获取当前已认证用户 ID。
|
||||||
|
|
||||||
|
### API 响应模式
|
||||||
|
所有 API 都返回 `ApiResponse<T>` 包装器,通过 `CustomExceptionHandle` 进行一致的错误处理。
|
||||||
|
|
||||||
|
### 添加新的定时任务
|
||||||
|
1. 在 `com.ycwl.basic.task` 包中创建类
|
||||||
|
2. 添加 `@Component` 和 `@Profile("prod")` 注解
|
||||||
|
3. 使用 `@Scheduled` 进行基于 cron 的执行
|
||||||
|
4. 遵循现有的错误处理和日志记录模式
|
148
src/main/java/com/ycwl/basic/controller/extern/AioDeviceController.java
vendored
Normal file
148
src/main/java/com/ycwl/basic/controller/extern/AioDeviceController.java
vendored
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
package com.ycwl.basic.controller.extern;
|
||||||
|
|
||||||
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
|
import com.ycwl.basic.mapper.AioDeviceMapper;
|
||||||
|
import com.ycwl.basic.mapper.MemberMapper;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceBannerEntity;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceEntity;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDevicePriceConfigEntity;
|
||||||
|
import com.ycwl.basic.model.aio.req.AioDeviceCreateOrderReq;
|
||||||
|
import com.ycwl.basic.model.aio.resp.AioDeviceCreateOrderResp;
|
||||||
|
import com.ycwl.basic.model.aio.resp.AioDeviceInfoResp;
|
||||||
|
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||||
|
import com.ycwl.basic.model.mobile.face.FaceRecognizeResp;
|
||||||
|
import com.ycwl.basic.model.mobile.goods.GoodsDetailVO;
|
||||||
|
import com.ycwl.basic.model.mobile.goods.GoodsReqQuery;
|
||||||
|
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
||||||
|
import com.ycwl.basic.model.pc.member.entity.MemberEntity;
|
||||||
|
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||||
|
import com.ycwl.basic.pay.entity.PayResponse;
|
||||||
|
import com.ycwl.basic.service.aio.AioDeviceService;
|
||||||
|
import com.ycwl.basic.service.mobile.GoodsService;
|
||||||
|
import com.ycwl.basic.service.pc.FaceService;
|
||||||
|
import com.ycwl.basic.service.pc.OrderService;
|
||||||
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
import com.ycwl.basic.utils.JwtTokenUtil;
|
||||||
|
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import jakarta.servlet.ServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@IgnoreToken
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/aio")
|
||||||
|
public class AioDeviceController {
|
||||||
|
@Autowired
|
||||||
|
private GoodsService goodsService;
|
||||||
|
@Autowired
|
||||||
|
private FaceService faceService;
|
||||||
|
@Autowired
|
||||||
|
private MemberMapper memberMapper;
|
||||||
|
@Autowired
|
||||||
|
private AioDeviceMapper aioDeviceMapper;
|
||||||
|
@Autowired
|
||||||
|
private AioDeviceService aioDeviceService;
|
||||||
|
@Autowired
|
||||||
|
private OrderService orderService;
|
||||||
|
|
||||||
|
@GetMapping("/info")
|
||||||
|
public ApiResponse<AioDeviceInfoResp> getDeviceInfo(HttpServletRequest request) {
|
||||||
|
String deviceId = request.getHeader("X-DeviceId");
|
||||||
|
AioDeviceEntity aioDevice = aioDeviceMapper.getByKey(deviceId);
|
||||||
|
if (aioDevice == null) {
|
||||||
|
return ApiResponse.fail("设备不存在");
|
||||||
|
}
|
||||||
|
List<AioDeviceBannerEntity> banners = aioDeviceMapper.getBannerByDeviceId(aioDevice.getId());
|
||||||
|
return ApiResponse.success(new AioDeviceInfoResp(aioDevice, banners));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/banners")
|
||||||
|
public ApiResponse<List<AioDeviceBannerEntity>> getBanners(HttpServletRequest request) {
|
||||||
|
String deviceId = request.getHeader("X-DeviceId");
|
||||||
|
AioDeviceEntity aioDevice = aioDeviceMapper.getByKey(deviceId);
|
||||||
|
if (aioDevice == null) {
|
||||||
|
return ApiResponse.fail("设备不存在");
|
||||||
|
}
|
||||||
|
List<AioDeviceBannerEntity> banners = aioDeviceMapper.getBannerByDeviceId(aioDevice.getId());
|
||||||
|
return ApiResponse.success(banners);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/config")
|
||||||
|
public ApiResponse<AioDevicePriceConfigEntity> getPriceConfig(HttpServletRequest request) {
|
||||||
|
String deviceId = request.getHeader("X-DeviceId");
|
||||||
|
AioDeviceEntity aioDevice = aioDeviceMapper.getByKey(deviceId);
|
||||||
|
if (aioDevice == null) {
|
||||||
|
return ApiResponse.fail("设备不存在");
|
||||||
|
}
|
||||||
|
AioDevicePriceConfigEntity config = aioDeviceMapper.getPriceConfigByDeviceId(aioDevice.getId());
|
||||||
|
return ApiResponse.success(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/faceUpload")
|
||||||
|
public ApiResponse<FaceRecognizeResp> faceUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
|
||||||
|
String deviceId = request.getHeader("X-DeviceId");
|
||||||
|
AioDeviceEntity aioDevice = aioDeviceMapper.getByKey(deviceId);
|
||||||
|
if (aioDevice == null) {
|
||||||
|
return ApiResponse.fail("设备不存在");
|
||||||
|
}
|
||||||
|
MemberEntity memberEntity = new MemberEntity();
|
||||||
|
memberEntity.setScenicId(aioDevice.getScenicId());
|
||||||
|
memberEntity.setCreateDate(new Date());
|
||||||
|
memberEntity.setId(SnowFlakeUtil.getLongId());
|
||||||
|
memberEntity.setNickname("用户");
|
||||||
|
memberMapper.add(memberEntity);
|
||||||
|
FaceRecognizeResp resp = faceService.faceUpload(file, aioDevice.getScenicId(), memberEntity.getId());
|
||||||
|
return ApiResponse.success(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("人脸信息")
|
||||||
|
@GetMapping("/{faceId}")
|
||||||
|
public ApiResponse<FaceRespVO> faceInfo(@PathVariable Long faceId) {
|
||||||
|
return faceService.getById(faceId);
|
||||||
|
}
|
||||||
|
@ApiOperation("照片商品列表")
|
||||||
|
@GetMapping("/{faceId}/photo")
|
||||||
|
public ApiResponse<List<GoodsDetailVO>> sourceGoodsList(@PathVariable Long faceId) {
|
||||||
|
GoodsReqQuery query = new GoodsReqQuery();
|
||||||
|
query.setSourceType(2);
|
||||||
|
query.setFaceId(faceId);
|
||||||
|
List<GoodsDetailVO> goodsDetailVOS = goodsService.sourceGoodsList(query);
|
||||||
|
return ApiResponse.success(goodsDetailVOS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("创建订单")
|
||||||
|
@PostMapping("/order")
|
||||||
|
public ApiResponse<AioDeviceCreateOrderResp> createOrder(HttpServletRequest request, @RequestBody AioDeviceCreateOrderReq req) {
|
||||||
|
String deviceId = request.getHeader("X-DeviceId");
|
||||||
|
AioDeviceEntity aioDevice = aioDeviceMapper.getByKey(deviceId);
|
||||||
|
if (aioDevice == null) {
|
||||||
|
return ApiResponse.fail("设备不存在");
|
||||||
|
}
|
||||||
|
return ApiResponse.success(aioDeviceService.createOrder(aioDevice, req));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("查询订单")
|
||||||
|
@GetMapping("/order/{orderId}")
|
||||||
|
public ApiResponse<PayResponse> queryOrder(HttpServletRequest request, @PathVariable("orderId") Long orderId) {
|
||||||
|
String deviceId = request.getHeader("X-DeviceId");
|
||||||
|
AioDeviceEntity aioDevice = aioDeviceMapper.getByKey(deviceId);
|
||||||
|
if (aioDevice == null) {
|
||||||
|
return ApiResponse.fail("设备不存在");
|
||||||
|
}
|
||||||
|
return ApiResponse.success(orderService.queryOrder(orderId));
|
||||||
|
}
|
||||||
|
}
|
@@ -14,8 +14,10 @@ import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO;
|
|||||||
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
||||||
import com.ycwl.basic.model.pc.member.entity.MemberEntity;
|
import com.ycwl.basic.model.pc.member.entity.MemberEntity;
|
||||||
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||||
|
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
|
||||||
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
|
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
|
||||||
import com.ycwl.basic.repository.VideoRepository;
|
import com.ycwl.basic.repository.VideoRepository;
|
||||||
|
import com.ycwl.basic.repository.VideoTaskRepository;
|
||||||
import com.ycwl.basic.service.mobile.AppScenicService;
|
import com.ycwl.basic.service.mobile.AppScenicService;
|
||||||
import com.ycwl.basic.service.mobile.GoodsService;
|
import com.ycwl.basic.service.mobile.GoodsService;
|
||||||
import com.ycwl.basic.service.pc.FaceService;
|
import com.ycwl.basic.service.pc.FaceService;
|
||||||
@@ -62,6 +64,8 @@ public class LyCompatibleController {
|
|||||||
private TaskTaskServiceImpl taskTaskServiceImpl;
|
private TaskTaskServiceImpl taskTaskServiceImpl;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, String> redisTemplate;
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private VideoTaskRepository videoTaskRepository;
|
||||||
|
|
||||||
@PostMapping("sendPhoto")
|
@PostMapping("sendPhoto")
|
||||||
@IgnoreToken
|
@IgnoreToken
|
||||||
@@ -198,6 +202,7 @@ public class LyCompatibleController {
|
|||||||
R response = R.ok();
|
R response = R.ok();
|
||||||
if (collect.get(0) == null) {
|
if (collect.get(0) == null) {
|
||||||
response.put("isgen", 1)
|
response.put("isgen", 1)
|
||||||
|
.put("face_id", faceVO.getId().toString())
|
||||||
.put("newvideo", Collections.emptyList())
|
.put("newvideo", Collections.emptyList())
|
||||||
.put("newuservideo", Collections.emptyList());
|
.put("newuservideo", Collections.emptyList());
|
||||||
return response;
|
return response;
|
||||||
@@ -208,6 +213,11 @@ public class LyCompatibleController {
|
|||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
VideoEntity videoRespVO = videoRepository.getVideo(contentPageVO.getContentId());
|
VideoEntity videoRespVO = videoRepository.getVideo(contentPageVO.getContentId());
|
||||||
map.put("id", videoRespVO.getId().toString());
|
map.put("id", videoRespVO.getId().toString());
|
||||||
|
map.put("task_id", videoRespVO.getTaskId().toString());
|
||||||
|
TaskEntity task = videoTaskRepository.getTaskById(videoRespVO.getTaskId());
|
||||||
|
if (task != null) {
|
||||||
|
map.put("face_id", String.valueOf(task.getFaceId()));
|
||||||
|
}
|
||||||
map.put("template_cover_image", contentPageVO.getTemplateCoverUrl());
|
map.put("template_cover_image", contentPageVO.getTemplateCoverUrl());
|
||||||
Date taskShotDate = taskTaskServiceImpl.getTaskShotDate(videoRespVO.getTaskId());
|
Date taskShotDate = taskTaskServiceImpl.getTaskShotDate(videoRespVO.getTaskId());
|
||||||
map.put("shoottime", DateUtil.format(taskShotDate, "yyyy-MM-dd HH:mm"));
|
map.put("shoottime", DateUtil.format(taskShotDate, "yyyy-MM-dd HH:mm"));
|
||||||
@@ -224,6 +234,7 @@ public class LyCompatibleController {
|
|||||||
List<Map<String, Object>> userVideoList = sourceGoodsList.stream().map(goodsDetailVO -> {
|
List<Map<String, Object>> userVideoList = sourceGoodsList.stream().map(goodsDetailVO -> {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("id", goodsDetailVO.getGoodsId().toString());
|
map.put("id", goodsDetailVO.getGoodsId().toString());
|
||||||
|
map.put("face_id", String.valueOf(goodsDetailVO.getFaceId()));
|
||||||
map.put("openid", openId);
|
map.put("openid", openId);
|
||||||
map.put("template_cover_image", goodsDetailVO.getUrl());
|
map.put("template_cover_image", goodsDetailVO.getUrl());
|
||||||
map.put("scenicname", goodsDetailVO.getScenicName());
|
map.put("scenicname", goodsDetailVO.getScenicName());
|
||||||
@@ -233,6 +244,8 @@ public class LyCompatibleController {
|
|||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
response
|
response
|
||||||
.put("isgen", taskStatusVO.getStatus() == 1 ? 0 : 1)
|
.put("isgen", taskStatusVO.getStatus() == 1 ? 0 : 1)
|
||||||
|
.put("member_id", faceVO.getMemberId().toString())
|
||||||
|
.put("face_id", faceVO.getId().toString())
|
||||||
.put("newvideo", videoList)
|
.put("newvideo", videoList)
|
||||||
.put("newuservideo", userVideoList);
|
.put("newuservideo", userVideoList);
|
||||||
redisTemplate.opsForValue().set("ly:"+openId, JSON.toJSONString(response), 5, TimeUnit.SECONDS);
|
redisTemplate.opsForValue().set("ly:"+openId, JSON.toJSONString(response), 5, TimeUnit.SECONDS);
|
||||||
|
@@ -78,4 +78,13 @@ AppFaceController {
|
|||||||
List<ContentPageVO> contentPageVOS = faceService.faceContentList(faceId);
|
List<ContentPageVO> contentPageVOS = faceService.faceContentList(faceId);
|
||||||
return ApiResponse.success(contentPageVOS);
|
return ApiResponse.success(contentPageVOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("绑定人脸")
|
||||||
|
@PostMapping("/{faceId}/bind")
|
||||||
|
public ApiResponse<String> bind(@PathVariable Long faceId) {
|
||||||
|
JwtInfo worker = JwtTokenUtil.getWorker();
|
||||||
|
Long userId = worker.getUserId();
|
||||||
|
faceService.bindFace(faceId, userId);
|
||||||
|
return ApiResponse.success("OK");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package com.ycwl.basic.controller.mobile.manage;
|
|||||||
|
|
||||||
import com.ycwl.basic.annotation.IgnoreToken;
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
import com.ycwl.basic.constant.BaseContextHandler;
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
|
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginOldRespVO;
|
||||||
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginReq;
|
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginReq;
|
||||||
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginRespVO;
|
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginRespVO;
|
||||||
import com.ycwl.basic.model.mobile.weChat.DTO.WeChatUserInfoDTO;
|
import com.ycwl.basic.model.mobile.weChat.DTO.WeChatUserInfoDTO;
|
||||||
@@ -49,8 +50,20 @@ public class AppScenicAccountController {
|
|||||||
@ApiOperation("登录")
|
@ApiOperation("登录")
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
@IgnoreToken
|
@IgnoreToken
|
||||||
public ApiResponse<ScenicLoginRespVO> login(@RequestBody ScenicLoginReq scenicLoginReq) throws Exception {
|
public ApiResponse<ScenicLoginOldRespVO> login(@RequestBody ScenicLoginReq scenicLoginReq) throws Exception {
|
||||||
return scenicService.login(scenicLoginReq);
|
ApiResponse<ScenicLoginRespVO> logined = scenicService.login(scenicLoginReq);
|
||||||
|
ScenicLoginOldRespVO vo = new ScenicLoginOldRespVO();
|
||||||
|
if (!logined.isSuccess()) {
|
||||||
|
return ApiResponse.fail(logined.getMsg());
|
||||||
|
}
|
||||||
|
vo.setId(logined.getData().getId());
|
||||||
|
vo.setScenicId(logined.getData().getScenicId().getFirst());
|
||||||
|
vo.setIsSuper(logined.getData().getIsSuper());
|
||||||
|
vo.setName(logined.getData().getName());
|
||||||
|
vo.setAccount(logined.getData().getAccount());
|
||||||
|
vo.setStatus(logined.getData().getStatus());
|
||||||
|
vo.setToken(logined.getData().getToken());
|
||||||
|
return ApiResponse.success(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/myScenicList")
|
@GetMapping("/myScenicList")
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
package com.ycwl.basic.controller.pc;
|
|
||||||
|
|
||||||
import com.ycwl.basic.annotation.IgnoreToken;
|
|
||||||
import com.ycwl.basic.model.pc.menu.entity.MenuEntity;
|
|
||||||
import com.ycwl.basic.service.pc.MenuService;
|
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author:longbinbin
|
|
||||||
* @Date:2024/12/3 10:03
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/menu/v1")
|
|
||||||
@Api(tags = "系统菜单管理")
|
|
||||||
public class MenuController {
|
|
||||||
|
|
||||||
private MenuService menuService;
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping(value = "/list/{type}")
|
|
||||||
@ApiOperation(value = " 菜单列表")
|
|
||||||
@IgnoreToken
|
|
||||||
public ApiResponse list(@PathVariable("type") Integer type) {
|
|
||||||
return menuService.list(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/add")
|
|
||||||
@ApiOperation(value = "添加菜单")
|
|
||||||
public ApiResponse add(@RequestBody MenuEntity menu) {
|
|
||||||
return menuService.add(menu);
|
|
||||||
}
|
|
||||||
@PostMapping("/update")
|
|
||||||
@ApiOperation(value = "修改菜单")
|
|
||||||
public ApiResponse update(@RequestBody MenuEntity menu) {
|
|
||||||
return menuService.update(menu);
|
|
||||||
}
|
|
||||||
@GetMapping("/delete/{id}")
|
|
||||||
@ApiOperation(value = "删除菜单")
|
|
||||||
public ApiResponse delete(@PathVariable("id") Long id) {
|
|
||||||
return menuService.deleteById(id);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,10 +1,14 @@
|
|||||||
package com.ycwl.basic.controller.pc;
|
package com.ycwl.basic.controller.pc;
|
||||||
|
|
||||||
import com.ycwl.basic.constant.BaseContextHandler;
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
|
import com.ycwl.basic.mapper.AdminUserMapper;
|
||||||
|
import com.ycwl.basic.model.pc.adminUser.entity.LoginEntity;
|
||||||
import com.ycwl.basic.model.pc.permission.entity.PermissionEntity;
|
import com.ycwl.basic.model.pc.permission.entity.PermissionEntity;
|
||||||
import com.ycwl.basic.model.pc.permission.req.PermissionSaveReq;
|
import com.ycwl.basic.model.pc.permission.req.PermissionSaveReq;
|
||||||
import com.ycwl.basic.model.pc.permission.resp.PermissionResp;
|
import com.ycwl.basic.model.pc.permission.resp.PermissionResp;
|
||||||
|
import com.ycwl.basic.model.pc.role.resp.RolePermissionResp;
|
||||||
import com.ycwl.basic.service.pc.PermissionService;
|
import com.ycwl.basic.service.pc.PermissionService;
|
||||||
|
import com.ycwl.basic.service.pc.RoleService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@@ -28,15 +32,29 @@ import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
|
|||||||
public class PermissionController {
|
public class PermissionController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private PermissionService permissionService;
|
private PermissionService permissionService;
|
||||||
|
@Autowired
|
||||||
|
private AdminUserMapper adminUserMapper;
|
||||||
|
@Autowired
|
||||||
|
private RoleService roleService;
|
||||||
|
|
||||||
@GetMapping("/get/")
|
@GetMapping("/get/")
|
||||||
public ApiResponse<PermissionResp> getPermissionByUser() {
|
public ApiResponse<PermissionResp> getPermissionByUser() {
|
||||||
String userId = BaseContextHandler.getUserId();
|
String userId = BaseContextHandler.getUserId();
|
||||||
|
if (MERCHANT.type.equals(BaseContextHandler.getRoleId())) {
|
||||||
PermissionEntity permission = permissionService.getPermissionByUserId(Long.parseLong(userId));
|
PermissionEntity permission = permissionService.getPermissionByUserId(Long.parseLong(userId));
|
||||||
if (permission == null || StringUtils.isEmpty(permission.getPermString())) {
|
if (permission == null || StringUtils.isEmpty(permission.getPermString())) {
|
||||||
return ApiResponse.success(new PermissionResp(new ArrayList<>(), new ArrayList<>()));
|
return ApiResponse.success(new PermissionResp(new ArrayList<>(), new ArrayList<>()));
|
||||||
}
|
}
|
||||||
return ApiResponse.success(new PermissionResp(Arrays.asList(StringUtils.split(permission.getPermString(), ",")), Arrays.asList(StringUtils.split(permission.getMenuString(), ","))));
|
return ApiResponse.success(new PermissionResp(Arrays.asList(StringUtils.split(permission.getPermString(), ",")), Arrays.asList(StringUtils.split(permission.getMenuString(), ","))));
|
||||||
|
} else {
|
||||||
|
// admin
|
||||||
|
LoginEntity login = adminUserMapper.getById(Long.parseLong(userId));
|
||||||
|
RolePermissionResp permissionByRoleId = roleService.getPermissionByRoleId(login.getRoleId());
|
||||||
|
if (permissionByRoleId == null) {
|
||||||
|
return ApiResponse.success(new PermissionResp(new ArrayList<>(), new ArrayList<>()));
|
||||||
|
}
|
||||||
|
return ApiResponse.success(new PermissionResp(Arrays.asList(StringUtils.split(permissionByRoleId.getPermStr(), ",")), Arrays.asList(StringUtils.split(permissionByRoleId.getMenuStr(), ","))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("根据用户ID查询权限信息")
|
@ApiOperation("根据用户ID查询权限信息")
|
||||||
|
@@ -2,16 +2,20 @@ package com.ycwl.basic.controller.pc;
|
|||||||
|
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.ycwl.basic.annotation.IgnoreToken;
|
import com.ycwl.basic.annotation.IgnoreToken;
|
||||||
|
import com.ycwl.basic.model.pc.permission.resp.PermissionResp;
|
||||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||||
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
||||||
|
import com.ycwl.basic.model.pc.role.resp.RolePermissionResp;
|
||||||
import com.ycwl.basic.service.pc.RoleService;
|
import com.ycwl.basic.service.pc.RoleService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
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 java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -24,34 +28,38 @@ public class RoleController {
|
|||||||
|
|
||||||
@PostMapping(value = "/page")
|
@PostMapping(value = "/page")
|
||||||
@ApiOperation(value = "角色列表分页查询")
|
@ApiOperation(value = "角色列表分页查询")
|
||||||
@IgnoreToken
|
|
||||||
public ApiResponse<PageInfo<RoleListRespVO>> page(@RequestBody RoleListReqVO roleListReqVO) {
|
public ApiResponse<PageInfo<RoleListRespVO>> page(@RequestBody RoleListReqVO roleListReqVO) {
|
||||||
return roleService.pageQuery(roleListReqVO);
|
return roleService.pageQuery(roleListReqVO);
|
||||||
}
|
}
|
||||||
@PostMapping(value = "/list")
|
@PostMapping(value = "/list")
|
||||||
@ApiOperation(value = "角色列表")
|
@ApiOperation(value = "角色列表")
|
||||||
@IgnoreToken
|
|
||||||
public ApiResponse<List<RoleListRespVO>> list(@RequestBody RoleListReqVO roleListReqVO) {
|
public ApiResponse<List<RoleListRespVO>> list(@RequestBody RoleListReqVO roleListReqVO) {
|
||||||
return roleService.list(roleListReqVO);
|
return roleService.list(roleListReqVO);
|
||||||
}
|
}
|
||||||
|
@GetMapping("/{roleId}/permission")
|
||||||
|
@ApiOperation(value = "角色权限列表")
|
||||||
|
public ApiResponse<PermissionResp> getPermissionByRoleId(@PathVariable("roleId") Long roleId) {
|
||||||
|
RolePermissionResp permission = roleService.getPermissionByRoleId(roleId);
|
||||||
|
if (permission == null) {
|
||||||
|
return ApiResponse.fail("角色不存在");
|
||||||
|
}
|
||||||
|
return ApiResponse.success(new PermissionResp(Arrays.asList(StringUtils.split(permission.getPermStr(), ",")), Arrays.asList(StringUtils.split(permission.getMenuStr(), ","))));
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/addOrUpdate")
|
@PostMapping(value = "/addOrUpdate")
|
||||||
@ApiOperation(value = "添加或更新角色")
|
@ApiOperation(value = "添加或更新角色")
|
||||||
@IgnoreToken
|
|
||||||
public ApiResponse addOrUpdate(@RequestBody AddOrUpdateRoleReqVO addOrUpdateRoleReqVO) {
|
public ApiResponse addOrUpdate(@RequestBody AddOrUpdateRoleReqVO addOrUpdateRoleReqVO) {
|
||||||
return roleService.addOrUpdate(addOrUpdateRoleReqVO);
|
return roleService.addOrUpdate(addOrUpdateRoleReqVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/delete/{id}")
|
@GetMapping(value = "/delete/{id}")
|
||||||
@ApiOperation(value = "删除")
|
@ApiOperation(value = "删除")
|
||||||
@IgnoreToken
|
|
||||||
public ApiResponse delete(@PathVariable("id") String id) {
|
public ApiResponse delete(@PathVariable("id") String id) {
|
||||||
return roleService.delete(id);
|
return roleService.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/updateReturnMenu/{id}")
|
@GetMapping(value = "/updateReturnMenu/{id}")
|
||||||
@ApiOperation(value = "编辑回显该角色当前菜单")
|
@ApiOperation(value = "编辑回显该角色当前菜单")
|
||||||
@IgnoreToken
|
|
||||||
public ApiResponse updateReturnMenu(@PathVariable("id") String id) {
|
public ApiResponse updateReturnMenu(@PathVariable("id") String id) {
|
||||||
return roleService.updateReturnMenu(id);
|
return roleService.updateReturnMenu(id);
|
||||||
}
|
}
|
||||||
@@ -60,7 +68,6 @@ public class RoleController {
|
|||||||
|
|
||||||
@GetMapping(value = "/updateStatus/{id}")
|
@GetMapping(value = "/updateStatus/{id}")
|
||||||
@ApiOperation(value = "更改角色类型状态")
|
@ApiOperation(value = "更改角色类型状态")
|
||||||
//@IgnoreToken
|
|
||||||
public ApiResponse updateStatus(@PathVariable("id") String id) {
|
public ApiResponse updateStatus(@PathVariable("id") String id) {
|
||||||
return roleService.updateStatus(id);
|
return roleService.updateStatus(id);
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@ import com.ycwl.basic.mapper.DeviceMapper;
|
|||||||
import com.ycwl.basic.mapper.FaceSampleMapper;
|
import com.ycwl.basic.mapper.FaceSampleMapper;
|
||||||
import com.ycwl.basic.mapper.SourceMapper;
|
import com.ycwl.basic.mapper.SourceMapper;
|
||||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||||
|
import com.ycwl.basic.model.pc.device.entity.DeviceCropConfig;
|
||||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||||
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
|
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
|
||||||
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
||||||
@@ -53,6 +54,8 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import java.awt.image.RasterFormatException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -66,7 +69,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static com.ycwl.basic.constant.StorageConstant.PHOTO_PATH;
|
import static com.ycwl.basic.constant.StorageConstant.PHOTO_PATH;
|
||||||
import static com.ycwl.basic.constant.StorageConstant.VIID_FACE;
|
import static com.ycwl.basic.constant.StorageConstant.VIID_FACE;
|
||||||
@@ -244,8 +246,14 @@ public class ViidController {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(device.getId());
|
DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(device.getId());
|
||||||
|
if (deviceConfig == null) {
|
||||||
|
log.warn("设备配置不存在:" + deviceID);
|
||||||
|
return new VIIDBaseResp(
|
||||||
|
new ResponseStatusObject(faceId, "/VIID/Faces", "0", "OK", sdfTime.format(new Date()))
|
||||||
|
);
|
||||||
|
}
|
||||||
int viidMode = 0;
|
int viidMode = 0;
|
||||||
if (deviceConfig != null && deviceConfig.getViidType() != null) {
|
if (deviceConfig.getViidType() != null) {
|
||||||
viidMode = deviceConfig.getViidType();
|
viidMode = deviceConfig.getViidType();
|
||||||
}
|
}
|
||||||
Date shotTime = null;
|
Date shotTime = null;
|
||||||
@@ -285,13 +293,15 @@ public class ViidController {
|
|||||||
if (viidMode == 0) {
|
if (viidMode == 0) {
|
||||||
// 遍历每个图片对象
|
// 遍历每个图片对象
|
||||||
// 先找到type14的图片
|
// 先找到type14的图片
|
||||||
List<SubImageInfoObject> type14ImageList = subImageList.getSubImageInfoObject().stream().filter(subImage -> "14".equals(subImage.getType())).collect(Collectors.toList());
|
List<SubImageInfoObject> type14ImageList = subImageList.getSubImageInfoObject().stream().filter(subImage -> "14".equals(subImage.getType())).toList();
|
||||||
for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) {
|
for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) {
|
||||||
// base64转换成MultipartFIle
|
// base64转换成MultipartFIle
|
||||||
MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData());
|
MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData());
|
||||||
String ext = subImage.getFileFormat();
|
String ext;
|
||||||
if (ext.equalsIgnoreCase("jpeg")) {
|
if (subImage.getFileFormat().equalsIgnoreCase("jpeg")) {
|
||||||
ext = "jpg";
|
ext = "jpg";
|
||||||
|
} else {
|
||||||
|
ext = subImage.getFileFormat();
|
||||||
}
|
}
|
||||||
IStorageAdapter adapter = StorageFactory.use("faces");
|
IStorageAdapter adapter = StorageFactory.use("faces");
|
||||||
// Type=11 人脸
|
// Type=11 人脸
|
||||||
@@ -318,7 +328,7 @@ public class ViidController {
|
|||||||
faceSampleMapper.updateScore(faceSample.getId(), addFaceResp.getScore());
|
faceSampleMapper.updateScore(faceSample.getId(), addFaceResp.getScore());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deviceConfig != null && Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) {
|
if (Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) {
|
||||||
DynamicTaskGenerator.addTask(faceSample.getId());
|
DynamicTaskGenerator.addTask(faceSample.getId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -328,7 +338,6 @@ public class ViidController {
|
|||||||
facePosition.setImgHeight(_subImage.getHeight());
|
facePosition.setImgHeight(_subImage.getHeight());
|
||||||
facePosition.setImgWidth(_subImage.getWidth());
|
facePosition.setImgWidth(_subImage.getWidth());
|
||||||
SourceEntity source = new SourceEntity();
|
SourceEntity source = new SourceEntity();
|
||||||
source.setId(SnowFlakeUtil.getLongId());
|
|
||||||
source.setDeviceId(device.getId());
|
source.setDeviceId(device.getId());
|
||||||
source.setScenicId(device.getScenicId());
|
source.setScenicId(device.getScenicId());
|
||||||
source.setFaceSampleId(newFaceSampleId);
|
source.setFaceSampleId(newFaceSampleId);
|
||||||
@@ -336,13 +345,44 @@ public class ViidController {
|
|||||||
source.setType(2);
|
source.setType(2);
|
||||||
// 上传oss
|
// 上传oss
|
||||||
MultipartFile _file = ImageUtils.base64ToMultipartFile(_subImage.getData());
|
MultipartFile _file = ImageUtils.base64ToMultipartFile(_subImage.getData());
|
||||||
|
ThreadPoolExecutor executor = getExecutor(scenicId);
|
||||||
|
executor.execute(() -> {
|
||||||
|
List<DeviceCropConfig> cropConfigs = deviceConfig._getCropConfig();
|
||||||
|
for (DeviceCropConfig cropConfig : cropConfigs) {
|
||||||
|
source.setId(SnowFlakeUtil.getLongId());
|
||||||
String filename = StorageUtil.joinPath(PHOTO_PATH, UUID.randomUUID() + "." + ext);
|
String filename = StorageUtil.joinPath(PHOTO_PATH, UUID.randomUUID() + "." + ext);
|
||||||
String _sourceUrl = scenicStorageAdapter.uploadFile(_file, filename);
|
MultipartFile _finalFile = _file;
|
||||||
|
if (cropConfig.getCropType() == 1) {
|
||||||
|
// 按固定位置截图
|
||||||
|
try {
|
||||||
|
_finalFile = ImageUtils.cropImage(_file, cropConfig.getTargetX(), cropConfig.getTargetY(), cropConfig.getTargetWidth(), cropConfig.getTargetHeight());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("裁切图片失败!", e);
|
||||||
|
} catch (RasterFormatException e) {
|
||||||
|
log.error("裁切图片出错!", e);
|
||||||
|
}
|
||||||
|
} else if (cropConfig.getCropType() == 2) {
|
||||||
|
// 按人脸位置
|
||||||
|
try {
|
||||||
|
int targetX = facePosition.getLtX() - (cropConfig.getTargetWidth() - facePosition.getWidth())/2;
|
||||||
|
int targetY = facePosition.getLtY() - (cropConfig.getTargetHeight() - facePosition.getHeight())/2;
|
||||||
|
_finalFile = ImageUtils.cropImage(_file, targetX, targetY, cropConfig.getTargetWidth(), cropConfig.getTargetHeight());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("裁切图片失败!", e);
|
||||||
|
} catch (RasterFormatException e) {
|
||||||
|
log.error("裁切图片出错!", e);
|
||||||
|
}
|
||||||
|
facePosition.setImgHeight(cropConfig.getTargetHeight());
|
||||||
|
facePosition.setImgWidth(cropConfig.getTargetWidth());
|
||||||
|
}
|
||||||
|
String _sourceUrl = scenicStorageAdapter.uploadFile(_finalFile, filename);
|
||||||
scenicStorageAdapter.setAcl(StorageAcl.PUBLIC_READ, filename);
|
scenicStorageAdapter.setAcl(StorageAcl.PUBLIC_READ, filename);
|
||||||
source.setUrl(_sourceUrl);
|
source.setUrl(_sourceUrl);
|
||||||
source.setPosJson(JSON.toJSONString(facePosition));
|
source.setPosJson(JSON.toJSONString(facePosition));
|
||||||
sourceMapper.add(source);
|
sourceMapper.add(source);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
log.info("人脸信息及原图{}张入库成功!设备ID:{}", type14ImageList.size(), deviceID);
|
log.info("人脸信息及原图{}张入库成功!设备ID:{}", type14ImageList.size(), deviceID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -278,7 +278,6 @@ public class BceFaceBodyAdapter implements IFaceBodyAdapter {
|
|||||||
try {
|
try {
|
||||||
AipFace client = getClient();
|
AipFace client = getClient();
|
||||||
HashMap<String, Object> options = new HashMap<>();
|
HashMap<String, Object> options = new HashMap<>();
|
||||||
options.put("quality_control", "LOW");
|
|
||||||
options.put("max_user_num", "50");
|
options.put("max_user_num", "50");
|
||||||
try {
|
try {
|
||||||
searchFaceLimiter.acquire();
|
searchFaceLimiter.acquire();
|
||||||
|
@@ -52,8 +52,9 @@ public class LeicaWatermarkOperator implements IOperator {
|
|||||||
public static int LOGO_EXTRA_BORDER = 20;
|
public static int LOGO_EXTRA_BORDER = 20;
|
||||||
public static int LOGO_FONT_SIZE = 38;
|
public static int LOGO_FONT_SIZE = 38;
|
||||||
public static Color logoTextColor = new Color(0x33, 0x33, 0x33);
|
public static Color logoTextColor = new Color(0x33, 0x33, 0x33);
|
||||||
public static int QRCODE_SIZE = 80;
|
public static int QRCODE_SIZE = 120;
|
||||||
public static int QRCODE_OFFSET_X = 5;
|
public static int QRCODE_OFFSET_X = 5;
|
||||||
|
public static int QRCODE_OFFSET_Y = 20;
|
||||||
public static int OFFSET_X = 80;
|
public static int OFFSET_X = 80;
|
||||||
public static int OFFSET_Y = 30;
|
public static int OFFSET_Y = 30;
|
||||||
public static int SCENIC_FONT_SIZE = 32;
|
public static int SCENIC_FONT_SIZE = 32;
|
||||||
@@ -106,13 +107,30 @@ public class LeicaWatermarkOperator implements IOperator {
|
|||||||
int dtLineHeight = datetimeFontMetrics.getHeight();
|
int dtLineHeight = datetimeFontMetrics.getHeight();
|
||||||
int scenicLineWidth = scenicFontMetrics.stringWidth(info.getScenicLine());
|
int scenicLineWidth = scenicFontMetrics.stringWidth(info.getScenicLine());
|
||||||
int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine());
|
int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine());
|
||||||
g2d.drawImage(qrcodeImage, newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y, newQrcodeWidth, newQrcodeHeight, null);
|
// 计算二维码的位置
|
||||||
|
int qrcodeX = newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth);
|
||||||
|
int qrcodeY = EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y - QRCODE_OFFSET_Y;
|
||||||
|
|
||||||
|
g2d.drawImage(qrcodeImage, qrcodeX, qrcodeY, newQrcodeWidth, newQrcodeHeight, null);
|
||||||
|
|
||||||
|
// 计算文字与二维码垂直居中对齐的Y坐标
|
||||||
|
int qrcodeTop = qrcodeY;
|
||||||
|
int qrcodeBottom = qrcodeTop + newQrcodeHeight;
|
||||||
|
int qrcodeCenter = (qrcodeTop + qrcodeBottom) / 2;
|
||||||
|
|
||||||
|
// 两行文字的总高度
|
||||||
|
int totalTextHeight = scenicLineHeight + dtLineHeight;
|
||||||
|
|
||||||
|
// 计算第一行文字的Y坐标(基线位置),使两行文字整体垂直居中于二维码
|
||||||
|
int textStartY = qrcodeCenter - totalTextHeight / 2 + scenicFontMetrics.getAscent();
|
||||||
|
|
||||||
g2d.setFont(scenicFont);
|
g2d.setFont(scenicFont);
|
||||||
g2d.setColor(scenicColor);
|
g2d.setColor(scenicColor);
|
||||||
g2d.drawString(info.getScenicLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + scenicLineHeight + scenicLineHeight * FONT_GLOBAL_OFFSET_PERCENT);
|
g2d.drawString(info.getScenicLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), textStartY);
|
||||||
|
|
||||||
g2d.setFont(datetimeFont);
|
g2d.setFont(datetimeFont);
|
||||||
g2d.setColor(datetimeColor);
|
g2d.setColor(datetimeColor);
|
||||||
g2d.drawString(info.getDatetimeLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + scenicLineHeight + dtLineHeight + dtLineHeight * FONT_GLOBAL_OFFSET_PERCENT);
|
g2d.drawString(info.getDatetimeLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), textStartY + scenicLineHeight);
|
||||||
String fileName = info.getWatermarkedFile().getName();
|
String fileName = info.getWatermarkedFile().getName();
|
||||||
String formatName = "jpg"; // 默认格式为 jpg
|
String formatName = "jpg"; // 默认格式为 jpg
|
||||||
if (fileName.endsWith(".png")) {
|
if (fileName.endsWith(".png")) {
|
||||||
@@ -133,7 +151,7 @@ public class LeicaWatermarkOperator implements IOperator {
|
|||||||
ImageWriteParam writeParam = writer.getDefaultWriteParam();
|
ImageWriteParam writeParam = writer.getDefaultWriteParam();
|
||||||
if (writeParam.canWriteCompressed()) {
|
if (writeParam.canWriteCompressed()) {
|
||||||
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||||
writeParam.setCompressionQuality(0.95f); // 设置写入质量为 95%
|
writeParam.setCompressionQuality(0.75f); // 设置写入质量为 75%
|
||||||
}
|
}
|
||||||
writer.write(null, new javax.imageio.IIOImage(newImage, null, null), writeParam);
|
writer.write(null, new javax.imageio.IIOImage(newImage, null, null), writeParam);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@@ -9,6 +9,7 @@ import javax.imageio.ImageWriteParam;
|
|||||||
import javax.imageio.ImageWriter;
|
import javax.imageio.ImageWriter;
|
||||||
import javax.imageio.stream.ImageOutputStream;
|
import javax.imageio.stream.ImageOutputStream;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -45,8 +46,9 @@ public class NormalWatermarkOperator implements IOperator {
|
|||||||
public static int EXTRA_BORDER_PX = 0;
|
public static int EXTRA_BORDER_PX = 0;
|
||||||
public static int OFFSET_Y = 90;
|
public static int OFFSET_Y = 90;
|
||||||
public static Color BG_COLOR = Color.WHITE;
|
public static Color BG_COLOR = Color.WHITE;
|
||||||
public static int QRCODE_SIZE = 100;
|
public static int QRCODE_SIZE = 150;
|
||||||
public static int QRCODE_OFFSET_X = 10;
|
public static int QRCODE_OFFSET_X = 10;
|
||||||
|
public static int QRCODE_OFFSET_Y = -20;
|
||||||
|
|
||||||
public static int SCENIC_FONT_SIZE = 42;
|
public static int SCENIC_FONT_SIZE = 42;
|
||||||
public static Color scenicColor = Color.white;
|
public static Color scenicColor = Color.white;
|
||||||
@@ -82,13 +84,29 @@ public class NormalWatermarkOperator implements IOperator {
|
|||||||
int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine());
|
int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine());
|
||||||
int offsetX = (newImage.getWidth() - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth)) / 2;
|
int offsetX = (newImage.getWidth() - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth)) / 2;
|
||||||
int offsetY = EXTRA_BORDER_PX + baseImage.getHeight() - OFFSET_Y - newQrcodeHeight;
|
int offsetY = EXTRA_BORDER_PX + baseImage.getHeight() - OFFSET_Y - newQrcodeHeight;
|
||||||
g2d.drawImage(qrcodeImage, offsetX, offsetY, newQrcodeWidth, newQrcodeHeight, null);
|
Shape originalClip = g2d.getClip();
|
||||||
|
Ellipse2D circle = new Ellipse2D.Double(offsetX, offsetY + QRCODE_OFFSET_Y, newQrcodeWidth, newQrcodeHeight);
|
||||||
|
g2d.setClip(circle);
|
||||||
|
g2d.drawImage(qrcodeImage, offsetX, offsetY + QRCODE_OFFSET_Y, newQrcodeWidth, newQrcodeHeight, null);
|
||||||
|
g2d.setClip(originalClip);
|
||||||
|
// 计算文字与二维码垂直居中对齐的Y坐标
|
||||||
|
int qrcodeTop = offsetY + QRCODE_OFFSET_Y;
|
||||||
|
int qrcodeBottom = qrcodeTop + newQrcodeHeight;
|
||||||
|
int qrcodeCenter = (qrcodeTop + qrcodeBottom) / 2;
|
||||||
|
|
||||||
|
// 两行文字的总高度
|
||||||
|
int totalTextHeight = scenicLineHeight + dtLineHeight;
|
||||||
|
|
||||||
|
// 计算第一行文字的Y坐标(基线位置),使两行文字整体垂直居中于二维码
|
||||||
|
int textStartY = qrcodeCenter - totalTextHeight / 2 + scenicFontMetrics.getAscent();
|
||||||
|
|
||||||
g2d.setFont(scenicFont);
|
g2d.setFont(scenicFont);
|
||||||
g2d.setColor(scenicColor);
|
g2d.setColor(scenicColor);
|
||||||
g2d.drawString(info.getScenicLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, offsetY + scenicLineHeight + FONT_GLOBAL_OFFSET_PERCENT * scenicLineHeight);
|
g2d.drawString(info.getScenicLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, textStartY);
|
||||||
|
|
||||||
g2d.setFont(datetimeFont);
|
g2d.setFont(datetimeFont);
|
||||||
g2d.setColor(datetimeColor);
|
g2d.setColor(datetimeColor);
|
||||||
g2d.drawString(info.getDatetimeLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, offsetY + scenicLineHeight + dtLineHeight + FONT_GLOBAL_OFFSET_PERCENT * dtLineHeight);
|
g2d.drawString(info.getDatetimeLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, textStartY + scenicLineHeight);
|
||||||
String fileName = info.getWatermarkedFile().getName();
|
String fileName = info.getWatermarkedFile().getName();
|
||||||
String formatName = "jpg"; // 默认格式为 jpg
|
String formatName = "jpg"; // 默认格式为 jpg
|
||||||
if (fileName.endsWith(".png")) {
|
if (fileName.endsWith(".png")) {
|
||||||
@@ -109,7 +127,7 @@ public class NormalWatermarkOperator implements IOperator {
|
|||||||
ImageWriteParam writeParam = writer.getDefaultWriteParam();
|
ImageWriteParam writeParam = writer.getDefaultWriteParam();
|
||||||
if (writeParam.canWriteCompressed()) {
|
if (writeParam.canWriteCompressed()) {
|
||||||
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||||
writeParam.setCompressionQuality(0.95f); // 设置写入质量为 95%
|
writeParam.setCompressionQuality(0.75f); // 设置写入质量为 75%
|
||||||
}
|
}
|
||||||
writer.write(null, new javax.imageio.IIOImage(newImage, null, null), writeParam);
|
writer.write(null, new javax.imageio.IIOImage(newImage, null, null), writeParam);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@@ -8,7 +8,12 @@ import com.ycwl.basic.constant.RequestConstant;
|
|||||||
import com.ycwl.basic.exception.CheckTokenException;
|
import com.ycwl.basic.exception.CheckTokenException;
|
||||||
import com.ycwl.basic.exception.MissTokenException;
|
import com.ycwl.basic.exception.MissTokenException;
|
||||||
import com.ycwl.basic.exception.PermissionException;
|
import com.ycwl.basic.exception.PermissionException;
|
||||||
|
import com.ycwl.basic.exception.TokenExpireException;
|
||||||
|
import com.ycwl.basic.mapper.AdminUserMapper;
|
||||||
|
import com.ycwl.basic.mapper.ScenicAccountMapper;
|
||||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||||
|
import com.ycwl.basic.model.pc.adminUser.entity.LoginEntity;
|
||||||
|
import com.ycwl.basic.model.pc.scenic.entity.ScenicAccountEntity;
|
||||||
import com.ycwl.basic.utils.JwtTokenUtil;
|
import com.ycwl.basic.utils.JwtTokenUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -23,14 +28,24 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.ycwl.basic.constant.JwtRoleConstant.ADMIN;
|
||||||
|
import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class AuthInterceptor implements HandlerInterceptor {
|
public class AuthInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RedisTemplate redisTemplate;
|
RedisTemplate redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private ScenicAccountMapper scenicAccountMapper;
|
||||||
|
@Autowired
|
||||||
|
private AdminUserMapper adminUserMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
@@ -68,10 +83,22 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|||||||
JwtInfo jwtInfo;
|
JwtInfo jwtInfo;
|
||||||
try {
|
try {
|
||||||
jwtInfo = JwtTokenUtil.parsingToken(token);
|
jwtInfo = JwtTokenUtil.parsingToken(token);
|
||||||
// LocalDateTime expireTime = jwtInfo.getExpireTime();
|
if (StringUtils.equals(jwtInfo.getRoleId(), MERCHANT.type)) {
|
||||||
// if (LocalDateTime.now(ZoneId.systemDefault()).isAfter(expireTime)) {
|
Long merchantId = jwtInfo.getUserId();
|
||||||
// throw new TokenExpireException("token过期");
|
ScenicAccountEntity account = scenicAccountMapper.findAccountById(merchantId.toString());
|
||||||
// }
|
LocalDateTime expireTime = jwtInfo.getExpireTime();
|
||||||
|
if (account.getUpdateTime().toInstant().getEpochSecond() != expireTime.atZone(ZoneId.systemDefault()).toEpochSecond()) {
|
||||||
|
throw new TokenExpireException("token过期");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(jwtInfo.getRoleId(), ADMIN.type)) {
|
||||||
|
Long adminId = jwtInfo.getUserId();
|
||||||
|
LoginEntity account = adminUserMapper.getById(adminId);
|
||||||
|
LocalDateTime expireTime = jwtInfo.getExpireTime();
|
||||||
|
if (account.getUpdateAt().toInstant().getEpochSecond() != expireTime.atZone(ZoneId.systemDefault()).toEpochSecond()) {
|
||||||
|
throw new TokenExpireException("token过期");
|
||||||
|
}
|
||||||
|
}
|
||||||
BaseContextHandler.setToken(token);
|
BaseContextHandler.setToken(token);
|
||||||
BaseContextHandler.setName(jwtInfo.getName());
|
BaseContextHandler.setName(jwtInfo.getName());
|
||||||
BaseContextHandler.setUserId(String.valueOf(jwtInfo.getUserId()));
|
BaseContextHandler.setUserId(String.valueOf(jwtInfo.getUserId()));
|
||||||
|
@@ -25,4 +25,6 @@ public interface AdminUserMapper {
|
|||||||
int updatePassword(UpdatePasswordReqVO updatePasswordReqVO);
|
int updatePassword(UpdatePasswordReqVO updatePasswordReqVO);
|
||||||
|
|
||||||
String getPasswordByAccount(@Param("id")String id);
|
String getPasswordByAccount(@Param("id")String id);
|
||||||
|
|
||||||
|
LoginEntity getById(Long id);
|
||||||
}
|
}
|
||||||
|
14
src/main/java/com/ycwl/basic/mapper/AioDeviceMapper.java
Normal file
14
src/main/java/com/ycwl/basic/mapper/AioDeviceMapper.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ycwl.basic.mapper;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceBannerEntity;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceEntity;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDevicePriceConfigEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AioDeviceMapper {
|
||||||
|
AioDeviceEntity getById(Long id);
|
||||||
|
AioDeviceEntity getByKey(String key);
|
||||||
|
List<AioDeviceBannerEntity> getBannerByDeviceId(Long deviceId);
|
||||||
|
AioDevicePriceConfigEntity getPriceConfigByDeviceId(Long deviceId);
|
||||||
|
}
|
11
src/main/java/com/ycwl/basic/mapper/ExtraDeviceMapper.java
Normal file
11
src/main/java/com/ycwl/basic/mapper/ExtraDeviceMapper.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.ycwl.basic.mapper;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ExtraDeviceMapper {
|
||||||
|
List<DeviceRespVO> listExtraDeviceByScenicId(Long scenicId);
|
||||||
|
}
|
@@ -2,6 +2,7 @@ package com.ycwl.basic.mapper;
|
|||||||
|
|
||||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
import com.ycwl.basic.model.pc.menu.MenuNode;
|
||||||
import com.ycwl.basic.model.pc.menu.entity.MenuEntity;
|
import com.ycwl.basic.model.pc.menu.entity.MenuEntity;
|
||||||
|
import com.ycwl.basic.model.pc.role.resp.RolePermissionResp;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
@@ -15,18 +16,6 @@ public interface MenuMapper {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int deleteRoleMenuByRoleId(@Param("id")String roleId);
|
int deleteRoleMenuByRoleId(@Param("id")String roleId);
|
||||||
int addRoleMenu(@Param("id")String roleId,@Param("list") List<Integer> list);
|
int addRoleMenu(@Param("id")String roleId,@Param("menuStr") String menuStr, @Param("permStr") String permStr);
|
||||||
int add(MenuEntity menuEntity);
|
RolePermissionResp getPermissionByRoleId(Long roleId);
|
||||||
|
|
||||||
List<MenuNode>getListByType(@Param("type")Integer type);
|
|
||||||
|
|
||||||
int update(MenuEntity menuEntity);
|
|
||||||
int deleteById(@Param("id")Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据菜单id删除角色菜单
|
|
||||||
* @param menuId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int deleteRoleMenuByMenuId(@Param("id")String menuId);
|
|
||||||
}
|
}
|
||||||
|
@@ -21,4 +21,6 @@ public interface RenderWorkerMapper {
|
|||||||
int updateStatus(Long id);
|
int updateStatus(Long id);
|
||||||
|
|
||||||
RenderWorkerEntity findByAccessKey(String accessKey);
|
RenderWorkerEntity findByAccessKey(String accessKey);
|
||||||
|
|
||||||
|
int updateHost(Long id, RenderWorkerEntity status);
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,7 @@ public interface SourceMapper {
|
|||||||
int addRelations(List<MemberSourceEntity> list);
|
int addRelations(List<MemberSourceEntity> list);
|
||||||
|
|
||||||
int updateRelation(MemberSourceEntity memberSourceEntity);
|
int updateRelation(MemberSourceEntity memberSourceEntity);
|
||||||
|
int freeRelations(List<Long> ids, int type);
|
||||||
|
|
||||||
List<SourceRespVO> queryByRelation(SourceReqQuery sourceReqQuery);
|
List<SourceRespVO> queryByRelation(SourceReqQuery sourceReqQuery);
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ public interface SourceMapper {
|
|||||||
List<SourceEntity> listVideoByFaceRelation(Long memberId, Long faceId);
|
List<SourceEntity> listVideoByFaceRelation(Long memberId, Long faceId);
|
||||||
|
|
||||||
List<SourceEntity> listImageByFaceRelation(Long memberId, Long faceId);
|
List<SourceEntity> listImageByFaceRelation(Long memberId, Long faceId);
|
||||||
|
List<MemberSourceEntity> listByFaceRelation(Long memberId, Long faceId, Integer type);
|
||||||
|
|
||||||
SourceEntity getEntity(Long id);
|
SourceEntity getEntity(Long id);
|
||||||
|
|
||||||
|
@@ -0,0 +1,35 @@
|
|||||||
|
package com.ycwl.basic.model.aio.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 智能设备横幅实体类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AioDeviceBannerEntity {
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备ID
|
||||||
|
*/
|
||||||
|
private Long deviceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 横幅URL
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 (0-禁用 1-启用)
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createAt;
|
||||||
|
}
|
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ycwl.basic.model.aio.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 智能设备实体类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AioDeviceEntity {
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接入密钥
|
||||||
|
*/
|
||||||
|
private String accessKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 (0-离线 1-在线)
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createAt;
|
||||||
|
}
|
@@ -0,0 +1,17 @@
|
|||||||
|
package com.ycwl.basic.model.aio.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AioDevicePriceConfigEntity {
|
||||||
|
/**
|
||||||
|
* 设备ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
private BigDecimal eachPrice;
|
||||||
|
private Integer status;
|
||||||
|
private Date createAt;
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ycwl.basic.model.aio.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AioDeviceCreateOrderReq {
|
||||||
|
private Long faceId;
|
||||||
|
private String payType;
|
||||||
|
private List<AioDeviceOrderItem> items;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class AioDeviceOrderItem {
|
||||||
|
private Long goodsId;
|
||||||
|
private Integer count;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package com.ycwl.basic.model.aio.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AioDeviceCreateOrderResp {
|
||||||
|
private boolean skipPay;
|
||||||
|
private Long orderId;
|
||||||
|
private String payCode;
|
||||||
|
}
|
@@ -0,0 +1,15 @@
|
|||||||
|
package com.ycwl.basic.model.aio.resp;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceBannerEntity;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceEntity;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AioDeviceInfoResp {
|
||||||
|
private AioDeviceEntity info;
|
||||||
|
private List<AioDeviceBannerEntity> banners;
|
||||||
|
}
|
@@ -19,6 +19,8 @@ import java.util.Date;
|
|||||||
public class GoodsDetailVO {
|
public class GoodsDetailVO {
|
||||||
@ApiModelProperty("商品名称")
|
@ApiModelProperty("商品名称")
|
||||||
private String goodsName;
|
private String goodsName;
|
||||||
|
@ApiModelProperty("人脸id")
|
||||||
|
private Long faceId;
|
||||||
@ApiModelProperty("景区id")
|
@ApiModelProperty("景区id")
|
||||||
private Long scenicId;
|
private Long scenicId;
|
||||||
@ApiModelProperty("景区名称")
|
@ApiModelProperty("景区名称")
|
||||||
@@ -41,6 +43,7 @@ public class GoodsDetailVO {
|
|||||||
private Integer isBuy;
|
private Integer isBuy;
|
||||||
private Integer isFree;
|
private Integer isFree;
|
||||||
private Integer parts;
|
private Integer parts;
|
||||||
|
private Integer sort;
|
||||||
public Integer getSourceType() {
|
public Integer getSourceType() {
|
||||||
return goodsType;
|
return goodsType;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ycwl.basic.model.mobile.scenic.account;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:longbinbin
|
||||||
|
* @Date:2024/12/13 9:44
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel("景区账号登录响应类")
|
||||||
|
public class ScenicLoginOldRespVO {
|
||||||
|
private Long id;
|
||||||
|
@ApiModelProperty("景区id")
|
||||||
|
private Long scenicId;
|
||||||
|
@ApiModelProperty("是否是超级管理员")
|
||||||
|
private Integer isSuper;
|
||||||
|
@ApiModelProperty("账号名称")
|
||||||
|
private String name;
|
||||||
|
@ApiModelProperty("账号")
|
||||||
|
private String account;
|
||||||
|
@ApiModelProperty("1启用 0禁用")
|
||||||
|
private Integer status;
|
||||||
|
private String token;
|
||||||
|
}
|
@@ -34,4 +34,6 @@ public class ContentPageVO {
|
|||||||
private Integer isBuy;
|
private Integer isBuy;
|
||||||
private BigDecimal duration;
|
private BigDecimal duration;
|
||||||
private Integer goodsType;
|
private Integer goodsType;
|
||||||
|
private int freeCount;
|
||||||
|
private Integer sort;
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,15 @@ package com.ycwl.basic.model.pc.adminUser.entity;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class LoginEntity {
|
public class LoginEntity {
|
||||||
private Long staffId;
|
private Long staffId;
|
||||||
private String staffName;
|
private String staffName;
|
||||||
private String account;
|
private String account;
|
||||||
private String password;
|
private String password;
|
||||||
private String roleId;
|
private Long roleId;
|
||||||
private String typeName;
|
private String typeName;
|
||||||
|
private Date updateAt;
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,5 @@ public class LoginRespVO {
|
|||||||
private String name;
|
private String name;
|
||||||
@ApiModelProperty(value = "角色名")
|
@ApiModelProperty(value = "角色名")
|
||||||
private String typeName;
|
private String typeName;
|
||||||
@ApiModelProperty(value = "菜单列表")
|
private boolean superAdmin;
|
||||||
private List<MenuNode> menuNodeList;
|
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
package com.ycwl.basic.model.pc.device.entity;
|
package com.ycwl.basic.model.pc.device.entity;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@TableName("device_config")
|
@TableName("device_config")
|
||||||
@@ -62,4 +66,18 @@ public class DeviceConfigEntity {
|
|||||||
private Integer videoFree;
|
private Integer videoFree;
|
||||||
private Long pairDevice;
|
private Long pairDevice;
|
||||||
private String videoCrop;
|
private String videoCrop;
|
||||||
|
private String cropConfig;
|
||||||
|
|
||||||
|
public List<DeviceCropConfig> _getCropConfig() {
|
||||||
|
if (cropConfig == null || cropConfig.isEmpty()) {
|
||||||
|
return Collections.singletonList(new DeviceCropConfig());
|
||||||
|
}
|
||||||
|
if (StringUtils.startsWith(cropConfig, "{")) {
|
||||||
|
return Collections.singletonList(JSON.parseObject(cropConfig, DeviceCropConfig.class));
|
||||||
|
}
|
||||||
|
if (StringUtils.startsWith(cropConfig, "[")) {
|
||||||
|
return JSON.parseArray(cropConfig, DeviceCropConfig.class);
|
||||||
|
}
|
||||||
|
return Collections.singletonList(new DeviceCropConfig());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
package com.ycwl.basic.model.pc.device.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DeviceCropConfig {
|
||||||
|
// 截图类型 0:无截图 1:固定截图 2:按人脸位置截图
|
||||||
|
private int cropType;
|
||||||
|
private Integer targetWidth;
|
||||||
|
private Integer targetHeight;
|
||||||
|
private Integer targetX;
|
||||||
|
private Integer targetY;
|
||||||
|
}
|
@@ -26,5 +26,6 @@ public class OrderItemEntity {
|
|||||||
* 商品ID,goods_type=1关联video.id,=2关联source.id
|
* 商品ID,goods_type=1关联video.id,=2关联source.id
|
||||||
*/
|
*/
|
||||||
private Long goodsId;
|
private Long goodsId;
|
||||||
|
private int count = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@ public class AddOrUpdateRoleReqVO {
|
|||||||
private String name;
|
private String name;
|
||||||
// @ApiModelProperty(value = "0系统角色 1业务角色")
|
// @ApiModelProperty(value = "0系统角色 1业务角色")
|
||||||
// private Integer type;
|
// private Integer type;
|
||||||
@ApiModelProperty(value = "菜单ID列表")
|
private List<String> permissions;
|
||||||
private List<Integer> menuIdList;
|
private List<String> menus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
package com.ycwl.basic.model.pc.role.resp;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class RolePermissionResp {
|
||||||
|
private String roleId;
|
||||||
|
private String permStr;
|
||||||
|
private String menuStr;
|
||||||
|
}
|
@@ -93,4 +93,7 @@ public class ScenicConfigEntity {
|
|||||||
private String videoSourcePackHint;
|
private String videoSourcePackHint;
|
||||||
|
|
||||||
private String extraNotificationTime;
|
private String extraNotificationTime;
|
||||||
|
|
||||||
|
private Integer photoFreeNum;
|
||||||
|
private Integer videoFreeNum;
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import com.wechat.pay.java.service.payments.jsapi.model.Payer;
|
|||||||
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
|
||||||
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
|
||||||
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
|
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.SettleInfo;
|
||||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
import com.wechat.pay.java.service.refund.RefundService;
|
import com.wechat.pay.java.service.refund.RefundService;
|
||||||
import com.wechat.pay.java.service.refund.model.AmountReq;
|
import com.wechat.pay.java.service.refund.model.AmountReq;
|
||||||
@@ -55,6 +56,7 @@ import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_NONCE;
|
|||||||
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SERIAL;
|
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SERIAL;
|
||||||
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SIGNATURE;
|
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_SIGNATURE;
|
||||||
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_TIMESTAMP;
|
import static com.wechat.pay.java.core.http.Constant.WECHAT_PAY_TIMESTAMP;
|
||||||
|
import static com.wechat.pay.java.service.refund.model.Status.PROCESSING;
|
||||||
import static com.wechat.pay.java.service.refund.model.Status.SUCCESS;
|
import static com.wechat.pay.java.service.refund.model.Status.SUCCESS;
|
||||||
|
|
||||||
public class WxMpPayAdapter implements IPayAdapter {
|
public class WxMpPayAdapter implements IPayAdapter {
|
||||||
@@ -66,6 +68,9 @@ public class WxMpPayAdapter implements IPayAdapter {
|
|||||||
public WxMpPayAdapter(WxMpPayConfig config) {
|
public WxMpPayAdapter(WxMpPayConfig config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
public WxMpPayConfig _config() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void loadConfig(Map<String, String> _config) {
|
public void loadConfig(Map<String, String> _config) {
|
||||||
this.config = new WxMpPayConfig();
|
this.config = new WxMpPayConfig();
|
||||||
@@ -77,12 +82,15 @@ public class WxMpPayAdapter implements IPayAdapter {
|
|||||||
this.config.setWxPublicKey(_config.get("wxPublicKey"));
|
this.config.setWxPublicKey(_config.get("wxPublicKey"));
|
||||||
this.config.setWxPublicKeyId(_config.get("wxPublicKeyId"));
|
this.config.setWxPublicKeyId(_config.get("wxPublicKeyId"));
|
||||||
this.config.setApiV3Key(_config.get("apiV3Key"));
|
this.config.setApiV3Key(_config.get("apiV3Key"));
|
||||||
|
if (_config.containsKey("enableProfitSharing")) {
|
||||||
|
this.config.setEnableProfitSharing(_config.get("enableProfitSharing").equals("true"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Config clientConfig;
|
private Config clientConfig;
|
||||||
|
|
||||||
private Config getConfig() {
|
public Config getConfig() {
|
||||||
if (clientConfig == null) {
|
if (clientConfig == null) {
|
||||||
if (StringUtils.isNotBlank(config.getWxPublicKeyId())) {
|
if (StringUtils.isNotBlank(config.getWxPublicKeyId())) {
|
||||||
clientConfig = new RSAPublicKeyConfig.Builder()
|
clientConfig = new RSAPublicKeyConfig.Builder()
|
||||||
@@ -126,6 +134,9 @@ public class WxMpPayAdapter implements IPayAdapter {
|
|||||||
Payer payer = new Payer();
|
Payer payer = new Payer();
|
||||||
payer.setOpenid(request.getUserIdentify());
|
payer.setOpenid(request.getUserIdentify());
|
||||||
prepayRequest.setPayer(payer);
|
prepayRequest.setPayer(payer);
|
||||||
|
SettleInfo settleInfo = new SettleInfo();
|
||||||
|
settleInfo.setProfitSharing(config.isEnableProfitSharing());
|
||||||
|
prepayRequest.setSettleInfo(settleInfo);
|
||||||
PrepayResponse response = service.prepay(prepayRequest);
|
PrepayResponse response = service.prepay(prepayRequest);
|
||||||
resp.setSuccess(true);
|
resp.setSuccess(true);
|
||||||
resp.setSkipPay(false);
|
resp.setSkipPay(false);
|
||||||
@@ -265,7 +276,7 @@ public class WxMpPayAdapter implements IPayAdapter {
|
|||||||
createRequest.setAmount(amountReq);
|
createRequest.setAmount(amountReq);
|
||||||
createRequest.setNotifyUrl(request.getNotifyUrl());
|
createRequest.setNotifyUrl(request.getNotifyUrl());
|
||||||
Refund refund = service.create(createRequest);
|
Refund refund = service.create(createRequest);
|
||||||
if (refund.getStatus() == SUCCESS) {
|
if (refund.getStatus() == SUCCESS || refund.getStatus() == PROCESSING) {
|
||||||
resp.setSuccess(true);
|
resp.setSuccess(true);
|
||||||
resp.setRefundNo(refund.getOutRefundNo());
|
resp.setRefundNo(refund.getOutRefundNo());
|
||||||
} else {
|
} else {
|
||||||
|
@@ -11,4 +11,5 @@ public class WxMpPayConfig {
|
|||||||
private String wxPublicKeyId;
|
private String wxPublicKeyId;
|
||||||
private String serialNumber;
|
private String serialNumber;
|
||||||
private String apiV3Key;
|
private String apiV3Key;
|
||||||
|
private boolean enableProfitSharing;
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@@ -52,6 +54,21 @@ public class RenderWorkerRepository {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
status.setUpdateAt(new Date());
|
status.setUpdateAt(new Date());
|
||||||
|
RenderWorkerEntity worker = new RenderWorkerEntity();
|
||||||
|
worker.setCpuCount(status.getCpu_count());
|
||||||
|
worker.setCpuUsage(status.getCpu_usage());
|
||||||
|
// 上报的是字节,存储的是兆
|
||||||
|
worker.setMemoryAvailable(status.getMemory_available().divide(BigDecimal.valueOf(1024 * 1024), RoundingMode.CEILING));
|
||||||
|
worker.setMemoryTotal(status.getMemory_total().divide(BigDecimal.valueOf(1024 * 1024), RoundingMode.CEILING));
|
||||||
|
|
||||||
|
worker.setPlatform(status.getPlatform());
|
||||||
|
worker.setRuntimeVersion(status.getRuntime_version());
|
||||||
|
worker.setSupportFeature(String.join(",", status.getSupport_feature()));
|
||||||
|
worker.setVersion(status.getVersion());
|
||||||
|
worker.setUpdateAt(status.getUpdateAt());
|
||||||
|
if (!redisTemplate.hasKey(key)) {
|
||||||
|
mapper.updateHost(id, worker);
|
||||||
|
}
|
||||||
redisTemplate.opsForValue().set(key, JSONObject.toJSONString(status), 1, TimeUnit.HOURS);
|
redisTemplate.opsForValue().set(key, JSONObject.toJSONString(status), 1, TimeUnit.HOURS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
package com.ycwl.basic.service.aio;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceEntity;
|
||||||
|
import com.ycwl.basic.model.aio.req.AioDeviceCreateOrderReq;
|
||||||
|
import com.ycwl.basic.model.aio.resp.AioDeviceCreateOrderResp;
|
||||||
|
|
||||||
|
public interface AioDeviceService {
|
||||||
|
AioDeviceCreateOrderResp createOrder(AioDeviceEntity aioDevice, AioDeviceCreateOrderReq req);
|
||||||
|
}
|
@@ -0,0 +1,104 @@
|
|||||||
|
package com.ycwl.basic.service.aio.impl;
|
||||||
|
|
||||||
|
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
|
||||||
|
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
|
||||||
|
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
|
||||||
|
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
|
||||||
|
import com.ycwl.basic.enums.OrderStateEnum;
|
||||||
|
import com.ycwl.basic.exception.BaseException;
|
||||||
|
import com.ycwl.basic.mapper.AioDeviceMapper;
|
||||||
|
import com.ycwl.basic.mapper.OrderMapper;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDeviceEntity;
|
||||||
|
import com.ycwl.basic.model.aio.entity.AioDevicePriceConfigEntity;
|
||||||
|
import com.ycwl.basic.model.aio.req.AioDeviceCreateOrderReq;
|
||||||
|
import com.ycwl.basic.model.aio.resp.AioDeviceCreateOrderResp;
|
||||||
|
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
||||||
|
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
|
||||||
|
import com.ycwl.basic.model.pc.order.entity.OrderItemEntity;
|
||||||
|
import com.ycwl.basic.pay.adapter.IPayAdapter;
|
||||||
|
import com.ycwl.basic.pay.adapter.WxMpPayAdapter;
|
||||||
|
import com.ycwl.basic.repository.FaceRepository;
|
||||||
|
import com.ycwl.basic.service.aio.AioDeviceService;
|
||||||
|
import com.ycwl.basic.service.pc.ScenicService;
|
||||||
|
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AioDeviceServiceImpl implements AioDeviceService {
|
||||||
|
@Autowired
|
||||||
|
private AioDeviceMapper aioDeviceMapper;
|
||||||
|
@Autowired
|
||||||
|
private ScenicService scenicService;
|
||||||
|
@Autowired
|
||||||
|
private FaceRepository faceRepository;
|
||||||
|
@Autowired
|
||||||
|
private OrderMapper orderMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AioDeviceCreateOrderResp createOrder(AioDeviceEntity aioDevice, AioDeviceCreateOrderReq req) {
|
||||||
|
// 询价
|
||||||
|
AioDevicePriceConfigEntity config = aioDeviceMapper.getPriceConfigByDeviceId(aioDevice.getId());
|
||||||
|
if (config == null) {
|
||||||
|
throw new BaseException("询价失败");
|
||||||
|
}
|
||||||
|
if (req.getItems() == null || req.getItems().isEmpty()) {
|
||||||
|
throw new BaseException("请选择商品");
|
||||||
|
}
|
||||||
|
FaceEntity face = faceRepository.getFace(req.getFaceId());
|
||||||
|
if (face == null) {
|
||||||
|
throw new BaseException("请选择人脸");
|
||||||
|
}
|
||||||
|
AioDeviceCreateOrderResp resp = new AioDeviceCreateOrderResp();
|
||||||
|
int sum = req.getItems().stream().mapToInt(AioDeviceCreateOrderReq.AioDeviceOrderItem::getCount).sum();
|
||||||
|
BigDecimal totalPrice = config.getEachPrice().multiply(new BigDecimal(sum));
|
||||||
|
if (totalPrice.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
resp.setSkipPay(true);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
OrderEntity order = new OrderEntity();
|
||||||
|
Long orderId = SnowFlakeUtil.getLongId();
|
||||||
|
order.setId(orderId);
|
||||||
|
order.setMemberId(face.getMemberId());
|
||||||
|
order.setFaceId(face.getId());
|
||||||
|
order.setScenicId(face.getScenicId());
|
||||||
|
order.setType(0);
|
||||||
|
List<OrderItemEntity> orderItems = req.getItems().stream().map(item -> {
|
||||||
|
OrderItemEntity orderItem = new OrderItemEntity();
|
||||||
|
orderItem.setOrderId(orderId);
|
||||||
|
orderItem.setGoodsId(item.getGoodsId());
|
||||||
|
orderItem.setGoodsType(4);
|
||||||
|
if (item.getCount() == null) {
|
||||||
|
item.setCount(1);
|
||||||
|
}
|
||||||
|
orderItem.setCount(item.getCount());
|
||||||
|
return orderItem;
|
||||||
|
}).toList();
|
||||||
|
order.setSlashPrice(totalPrice);
|
||||||
|
order.setPrice(totalPrice);
|
||||||
|
order.setPayPrice(totalPrice);
|
||||||
|
order.setStatus(OrderStateEnum.UNPAID.getState());
|
||||||
|
orderMapper.add(order);
|
||||||
|
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
||||||
|
// 支付
|
||||||
|
IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(aioDevice.getScenicId());
|
||||||
|
if (scenicPayAdapter instanceof WxMpPayAdapter adapter) {
|
||||||
|
NativePayService service = new NativePayService.Builder().config(adapter.getConfig()).build();
|
||||||
|
PrepayRequest request = new PrepayRequest();
|
||||||
|
request.setAppid(adapter._config().getAppId());
|
||||||
|
request.setMchid(adapter._config().getMerchantId());
|
||||||
|
request.setDescription("打印订单");
|
||||||
|
request.setOutTradeNo(SnowFlakeUtil.getId());
|
||||||
|
request.setNotifyUrl("https://zhentuai.com/api/mobile/wx/pay/v1/"+aioDevice.getScenicId()+"/payNotify");
|
||||||
|
Amount amount = new Amount();
|
||||||
|
amount.setTotal(totalPrice.multiply(new BigDecimal(100)).intValue());
|
||||||
|
request.setAmount(amount);
|
||||||
|
PrepayResponse response = service.prepay(request);
|
||||||
|
resp.setPayCode(response.getCodeUrl());
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
}
|
@@ -29,6 +29,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.ycwl.basic.constant.JwtRoleConstant.APP_USER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author:songmingsong
|
* @Author:songmingsong
|
||||||
*/
|
*/
|
||||||
@@ -116,6 +118,7 @@ public class AppMemberServiceImpl implements AppMemberService {
|
|||||||
jwtInfo.setUserId(memberRespVO.getId());
|
jwtInfo.setUserId(memberRespVO.getId());
|
||||||
jwtInfo.setName(memberRespVO.getNickname());
|
jwtInfo.setName(memberRespVO.getNickname());
|
||||||
jwtInfo.setPhone(memberRespVO.getPhone());
|
jwtInfo.setPhone(memberRespVO.getPhone());
|
||||||
|
jwtInfo.setRoleId(APP_USER.type);
|
||||||
|
|
||||||
String jwt = jwtTokenUtil.generateToken(jwtInfo);
|
String jwt = jwtTokenUtil.generateToken(jwtInfo);
|
||||||
Map<String, Object> resMap = new HashMap<>();
|
Map<String, Object> resMap = new HashMap<>();
|
||||||
|
@@ -11,19 +11,24 @@ import com.ycwl.basic.model.mobile.scenic.ScenicDeviceCountVO;
|
|||||||
import com.ycwl.basic.model.mobile.scenic.ScenicIndexVO;
|
import com.ycwl.basic.model.mobile.scenic.ScenicIndexVO;
|
||||||
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginReq;
|
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginReq;
|
||||||
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginRespVO;
|
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginRespVO;
|
||||||
|
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||||
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
|
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
|
||||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicAccountEntity;
|
import com.ycwl.basic.model.pc.scenic.entity.ScenicAccountEntity;
|
||||||
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
||||||
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
||||||
|
import com.ycwl.basic.repository.DeviceRepository;
|
||||||
import com.ycwl.basic.service.mobile.AppScenicService;
|
import com.ycwl.basic.service.mobile.AppScenicService;
|
||||||
import com.ycwl.basic.service.pc.ScenicAccountService;
|
import com.ycwl.basic.service.pc.ScenicAccountService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import com.ycwl.basic.utils.JwtTokenUtil;
|
import com.ycwl.basic.utils.JwtTokenUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
|
import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
|
||||||
@@ -46,6 +51,12 @@ public class AppScenicServiceImpl implements AppScenicService {
|
|||||||
private JwtTokenUtil jwtTokenUtil;
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ScenicAccountService scenicAccountService;
|
private ScenicAccountService scenicAccountService;
|
||||||
|
@Autowired
|
||||||
|
private DeviceRepository deviceRepository;
|
||||||
|
@Autowired
|
||||||
|
private ExtraDeviceMapper extraDeviceMapper;
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<PageInfo<ScenicAppVO>> pageQuery(ScenicReqQuery scenicReqQuery) {
|
public ApiResponse<PageInfo<ScenicAppVO>> pageQuery(ScenicReqQuery scenicReqQuery) {
|
||||||
@@ -88,7 +99,7 @@ public class AppScenicServiceImpl implements AppScenicService {
|
|||||||
jwtInfo.setAccount(scenicAccount.getAccount());
|
jwtInfo.setAccount(scenicAccount.getAccount());
|
||||||
jwtInfo.setUserId(scenicAccount.getId());
|
jwtInfo.setUserId(scenicAccount.getId());
|
||||||
jwtInfo.setRoleId(MERCHANT.type);
|
jwtInfo.setRoleId(MERCHANT.type);
|
||||||
String token = jwtTokenUtil.generateToken(jwtInfo);
|
String token = jwtTokenUtil.generateToken(jwtInfo, scenicAccount.getUpdateTime());
|
||||||
|
|
||||||
ScenicLoginRespVO scenicLoginRespVO = new ScenicLoginRespVO();
|
ScenicLoginRespVO scenicLoginRespVO = new ScenicLoginRespVO();
|
||||||
BeanUtil.copyProperties(scenicAccount,scenicLoginRespVO);
|
BeanUtil.copyProperties(scenicAccount,scenicLoginRespVO);
|
||||||
@@ -105,6 +116,40 @@ public class AppScenicServiceImpl implements AppScenicService {
|
|||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<DeviceRespVO>> getDevices(Long scenicId) {
|
public ApiResponse<List<DeviceRespVO>> getDevices(Long scenicId) {
|
||||||
List<DeviceRespVO> deviceRespVOList = deviceMapper.listByScenicIdWithWVP(scenicId);
|
List<DeviceRespVO> deviceRespVOList = deviceMapper.listByScenicIdWithWVP(scenicId);
|
||||||
|
for (DeviceRespVO deviceRespVO : deviceRespVOList) {
|
||||||
|
DeviceEntity onlineStatus = deviceRepository.getOnlineStatus(deviceRespVO.getId());
|
||||||
|
if (onlineStatus != null) {
|
||||||
|
deviceRespVO.setUpdateAt(onlineStatus.getKeepaliveAt());
|
||||||
|
deviceRespVO.setKeepaliveAt(onlineStatus.getKeepaliveAt());
|
||||||
|
if (new Date().getTime() - onlineStatus.getKeepaliveAt().getTime() > 300000) {
|
||||||
|
deviceRespVO.setOnline(0);
|
||||||
|
} else {
|
||||||
|
deviceRespVO.setOnline(onlineStatus.getOnline());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deviceRespVO.setOnline(0);
|
||||||
|
deviceRespVO.setKeepaliveAt(null);
|
||||||
|
deviceRespVO.setUpdateAt(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<DeviceRespVO> extraDeviceList = extraDeviceMapper.listExtraDeviceByScenicId(scenicId);
|
||||||
|
for (DeviceRespVO deviceRespVO : extraDeviceList) {
|
||||||
|
if (redisTemplate.hasKey("ext_device:online:"+deviceRespVO.getNo())) {
|
||||||
|
String onlineTs = redisTemplate.opsForValue().get("ext_device:online:"+deviceRespVO.getNo());
|
||||||
|
if (!StringUtils.isNumeric(onlineTs)) {
|
||||||
|
deviceRespVO.setOnline(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Long ts = Long.parseLong(onlineTs);
|
||||||
|
Date keepaliveAt = new Date(ts*1000);
|
||||||
|
deviceRespVO.setUpdateAt(keepaliveAt);
|
||||||
|
deviceRespVO.setKeepaliveAt(keepaliveAt);
|
||||||
|
deviceRespVO.setOnline(keepaliveAt.getTime() > System.currentTimeMillis()-1000*60*5 ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
deviceRespVO.setOnline(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deviceRespVOList.addAll(0, extraDeviceList);
|
||||||
return ApiResponse.success(deviceRespVOList);
|
return ApiResponse.success(deviceRespVOList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -370,14 +370,14 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
|
|||||||
//当前周期的推送订阅人数
|
//当前周期的推送订阅人数
|
||||||
vo.setNowPushOfPeopleNum(data.getPushOfMemberNum());
|
vo.setNowPushOfPeopleNum(data.getPushOfMemberNum());
|
||||||
//当前周期的预览视频人数
|
//当前周期的预览视频人数
|
||||||
vo.setNowPreviewVideoOfPeopleNum(data.getPreviewOfVideoNum());
|
vo.setNowPreviewVideoOfPeopleNum(data.getPreviewVideoOfMemberNum());
|
||||||
}else if(cycle==2){
|
}else if(cycle==2){
|
||||||
//上一个周期的扫码访问人数
|
//上一个周期的扫码访问人数
|
||||||
vo.setPreviousScanCodeOfPeopleNum(data.getScanCodeVisitorOfMemberNum());
|
vo.setPreviousScanCodeOfPeopleNum(data.getScanCodeVisitorOfMemberNum());
|
||||||
//上一个周期的推送订阅人数
|
//上一个周期的推送订阅人数
|
||||||
vo.setPreviousPushOfPeopleNum(data.getPushOfMemberNum());
|
vo.setPreviousPushOfPeopleNum(data.getPushOfMemberNum());
|
||||||
//上一个周期的预览视频人数
|
//上一个周期的预览视频人数
|
||||||
vo.setPreviousPreviewVideoOfPeopleNum(data.getPreviewOfVideoNum());
|
vo.setPreviousPreviewVideoOfPeopleNum(data.getPreviewVideoOfMemberNum());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -75,8 +75,6 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SourceMapper sourceMapper;
|
private SourceMapper sourceMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ScenicMapper scenicMapper;
|
|
||||||
@Autowired
|
|
||||||
private FaceMapper faceMapper;
|
private FaceMapper faceMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private TemplateRepository templateRepository;
|
private TemplateRepository templateRepository;
|
||||||
@@ -87,8 +85,6 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ScenicRepository scenicRepository;
|
private ScenicRepository scenicRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private OrderRepository orderRepository;
|
|
||||||
@Autowired
|
|
||||||
private OrderBiz orderBiz;
|
private OrderBiz orderBiz;
|
||||||
@Autowired
|
@Autowired
|
||||||
private FaceRepository faceRepository;
|
private FaceRepository faceRepository;
|
||||||
@@ -98,10 +94,18 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
private DeviceRepository deviceRepository;
|
private DeviceRepository deviceRepository;
|
||||||
|
|
||||||
public ApiResponse<List<GoodsPageVO>> goodsList(GoodsReqQuery query) {
|
public ApiResponse<List<GoodsPageVO>> goodsList(GoodsReqQuery query) {
|
||||||
|
Long scenicId = query.getScenicId();
|
||||||
|
if (query.getFaceId() != null) {
|
||||||
|
FaceEntity face = faceRepository.getFace(query.getFaceId());
|
||||||
|
if (face == null) {
|
||||||
|
return ApiResponse.success(Collections.emptyList());
|
||||||
|
}
|
||||||
|
scenicId = face.getScenicId();
|
||||||
|
}
|
||||||
//查询原素材
|
//查询原素材
|
||||||
List<GoodsPageVO> goodsList = new ArrayList<>();
|
List<GoodsPageVO> goodsList = new ArrayList<>();
|
||||||
VideoReqQuery videoReqQuery = new VideoReqQuery();
|
VideoReqQuery videoReqQuery = new VideoReqQuery();
|
||||||
videoReqQuery.setScenicId(query.getScenicId());
|
videoReqQuery.setScenicId(scenicId);
|
||||||
videoReqQuery.setIsBuy(query.getIsBuy());
|
videoReqQuery.setIsBuy(query.getIsBuy());
|
||||||
videoReqQuery.setFaceId(query.getFaceId());
|
videoReqQuery.setFaceId(query.getFaceId());
|
||||||
videoReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
|
videoReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
|
||||||
@@ -121,25 +125,21 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||||
sourceReqQuery.setScenicId(query.getScenicId());
|
sourceReqQuery.setScenicId(scenicId);
|
||||||
sourceReqQuery.setIsBuy(query.getIsBuy());
|
sourceReqQuery.setIsBuy(query.getIsBuy());
|
||||||
sourceReqQuery.setFaceId(query.getFaceId());
|
sourceReqQuery.setFaceId(query.getFaceId());
|
||||||
sourceReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
|
sourceReqQuery.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
|
||||||
//查询源素材
|
//查询源素材
|
||||||
List<SourceRespVO> sourceList = sourceMapper.queryByRelation(sourceReqQuery);
|
List<SourceRespVO> sourceList = sourceMapper.queryByRelation(sourceReqQuery);
|
||||||
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(query.getScenicId());
|
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
|
||||||
List<GoodsPageVO> sourceGoods = sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getFaceId)).entrySet().stream().flatMap((faceEntry) -> {
|
List<GoodsPageVO> sourceGoods = sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getFaceId)).entrySet().stream().flatMap((faceEntry) -> {
|
||||||
Long faceId = faceEntry.getKey();
|
Long faceId = faceEntry.getKey();
|
||||||
List<SourceRespVO> goods = faceEntry.getValue();
|
List<SourceRespVO> goods = faceEntry.getValue();
|
||||||
return goods.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).keySet().stream().filter(type -> {
|
return goods.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).keySet().stream().filter(type -> {
|
||||||
if (Integer.valueOf(1).equals(type)) {
|
if (Integer.valueOf(1).equals(type)) {
|
||||||
if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
|
return !Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (Integer.valueOf(2).equals(type)) {
|
} else if (Integer.valueOf(2).equals(type)) {
|
||||||
if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceImage())) {
|
return !Integer.valueOf(1).equals(scenicConfig.getDisableSourceImage());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).map(type -> {
|
}).map(type -> {
|
||||||
@@ -156,7 +156,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
goodsPageVO.setScenicId(query.getScenicId());
|
goodsPageVO.setScenicId(query.getScenicId());
|
||||||
return goodsPageVO;
|
return goodsPageVO;
|
||||||
});
|
});
|
||||||
}).collect(Collectors.toList());
|
}).toList();
|
||||||
if (!sourceGoods.isEmpty()) {
|
if (!sourceGoods.isEmpty()) {
|
||||||
if (goodsList.size() > 2) {
|
if (goodsList.size() > 2) {
|
||||||
goodsList.addAll(2, sourceGoods);
|
goodsList.addAll(2, sourceGoods);
|
||||||
@@ -175,11 +175,11 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
}
|
}
|
||||||
Integer sourceType = query.getSourceType();
|
Integer sourceType = query.getSourceType();
|
||||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||||
sourceReqQuery.setScenicId(query.getScenicId());
|
sourceReqQuery.setScenicId(face.getScenicId());
|
||||||
sourceReqQuery.setIsBuy(query.getIsBuy());
|
sourceReqQuery.setIsBuy(query.getIsBuy());
|
||||||
sourceReqQuery.setMemberId(face.getMemberId());
|
sourceReqQuery.setMemberId(face.getMemberId());
|
||||||
sourceReqQuery.setType(sourceType);
|
sourceReqQuery.setType(sourceType);
|
||||||
sourceReqQuery.setFaceId(query.getFaceId());
|
sourceReqQuery.setFaceId(face.getId());
|
||||||
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
|
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
|
||||||
List<GoodsDetailVO> goodsDetailVOList = new ArrayList<>();
|
List<GoodsDetailVO> goodsDetailVOList = new ArrayList<>();
|
||||||
|
|
||||||
@@ -195,6 +195,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
int i=1;
|
int i=1;
|
||||||
for (SourceRespVO sourceRespVO : list) {
|
for (SourceRespVO sourceRespVO : list) {
|
||||||
GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
|
GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
|
||||||
|
goodsDetailVO.setFaceId(sourceRespVO.getFaceId());
|
||||||
goodsDetailVO.setGoodsId(sourceRespVO.getId());
|
goodsDetailVO.setGoodsId(sourceRespVO.getId());
|
||||||
String shootingTime = DateUtil.format(sourceRespVO.getCreateTime(), "yyyy.MM.dd HH:mm:ss");
|
String shootingTime = DateUtil.format(sourceRespVO.getCreateTime(), "yyyy.MM.dd HH:mm:ss");
|
||||||
if (i < 10) {
|
if (i < 10) {
|
||||||
@@ -205,6 +206,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
goodsDetailVO.setScenicId(sourceRespVO.getScenicId());
|
goodsDetailVO.setScenicId(sourceRespVO.getScenicId());
|
||||||
goodsDetailVO.setScenicName(sourceRespVO.getScenicName());
|
goodsDetailVO.setScenicName(sourceRespVO.getScenicName());
|
||||||
goodsDetailVO.setGoodsType(sourceType);
|
goodsDetailVO.setGoodsType(sourceType);
|
||||||
|
goodsDetailVO.setFaceId(face.getId());
|
||||||
goodsDetailVO.setGoodsId(sourceRespVO.getId());
|
goodsDetailVO.setGoodsId(sourceRespVO.getId());
|
||||||
goodsDetailVO.setIsFree(sourceRespVO.getIsFree());
|
goodsDetailVO.setIsFree(sourceRespVO.getIsFree());
|
||||||
goodsDetailVO.setIsBuy(sourceRespVO.getIsBuy());
|
goodsDetailVO.setIsBuy(sourceRespVO.getIsBuy());
|
||||||
@@ -277,6 +279,9 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TaskEntity task = videoTaskRepository.getTaskById(videoRespVO.getTaskId());
|
TaskEntity task = videoTaskRepository.getTaskById(videoRespVO.getTaskId());
|
||||||
|
if (task == null) {
|
||||||
|
return ApiResponse.fail("该vlog不存在或已失效");
|
||||||
|
}
|
||||||
JSONObject paramJson = JSON.parseObject(task.getTaskParams());
|
JSONObject paramJson = JSON.parseObject(task.getTaskParams());
|
||||||
AtomicInteger deviceCount = new AtomicInteger();
|
AtomicInteger deviceCount = new AtomicInteger();
|
||||||
goodsDetailVO.setShotTime(taskTaskService.getTaskShotDate(task.getId()));
|
goodsDetailVO.setShotTime(taskTaskService.getTaskShotDate(task.getId()));
|
||||||
@@ -511,11 +516,11 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
}
|
}
|
||||||
Integer sourceType = query.getSourceType();
|
Integer sourceType = query.getSourceType();
|
||||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||||
sourceReqQuery.setScenicId(query.getScenicId());
|
sourceReqQuery.setScenicId(face.getScenicId());
|
||||||
sourceReqQuery.setIsBuy(query.getIsBuy());
|
sourceReqQuery.setIsBuy(query.getIsBuy());
|
||||||
sourceReqQuery.setMemberId(face.getMemberId());
|
sourceReqQuery.setMemberId(face.getMemberId());
|
||||||
sourceReqQuery.setType(sourceType);
|
sourceReqQuery.setType(sourceType);
|
||||||
sourceReqQuery.setFaceId(query.getFaceId());
|
sourceReqQuery.setFaceId(face.getId());
|
||||||
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
|
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
|
||||||
if (!Integer.valueOf(2).equals(query.getSourceType())) {
|
if (!Integer.valueOf(2).equals(query.getSourceType())) {
|
||||||
return list.stream().map(source -> {
|
return list.stream().map(source -> {
|
||||||
@@ -535,7 +540,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
goodsUrlVO.setCreateTime(source.getCreateTime());
|
goodsUrlVO.setCreateTime(source.getCreateTime());
|
||||||
return goodsUrlVO;
|
return goodsUrlVO;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), query.getScenicId(), query.getSourceType(), query.getFaceId());
|
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), query.getSourceType(), face.getId());
|
||||||
if (!isBuy.isBuy()) {
|
if (!isBuy.isBuy()) {
|
||||||
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(face.getScenicId());
|
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(face.getScenicId());
|
||||||
if (scenicConfig != null && ((scenicConfig.getAntiScreenRecordType() & 2) == 0)) {
|
if (scenicConfig != null && ((scenicConfig.getAntiScreenRecordType() & 2) == 0)) {
|
||||||
@@ -607,7 +612,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
sourceReqQuery.setFaceId(query.getFaceId());
|
sourceReqQuery.setFaceId(query.getFaceId());
|
||||||
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
|
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
|
||||||
if (query.getGoodsId() != null) {
|
if (query.getGoodsId() != null) {
|
||||||
list = list.stream().filter(source -> source.getId().equals(query.getGoodsId())).collect(Collectors.toList());
|
list = list.stream().filter(source -> source.getId().equals(query.getGoodsId())).toList();
|
||||||
}
|
}
|
||||||
if (!Integer.valueOf(2).equals(query.getSourceType())) {
|
if (!Integer.valueOf(2).equals(query.getSourceType())) {
|
||||||
return list.stream().map(source -> {
|
return list.stream().map(source -> {
|
||||||
@@ -628,8 +633,8 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).count();
|
}).count();
|
||||||
|
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), query.getSourceType(), face.getId());
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), query.getScenicId(), query.getSourceType(), query.getFaceId());
|
|
||||||
if (!isBuy.isBuy()) {
|
if (!isBuy.isBuy()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -648,7 +653,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
log.warn("未配置小程序参数,无法生成二维码");
|
log.warn("未配置小程序参数,无法生成二维码");
|
||||||
return defaultUrlList;
|
return defaultUrlList;
|
||||||
}
|
}
|
||||||
if (scenicConfig != null && scenicConfig.getWatermarkType() != null) {
|
if (scenicConfig != null && scenicConfig.getWatermarkType() != null && !isBuy.isBuy()) {
|
||||||
ImageWatermarkOperatorEnum type = ImageWatermarkOperatorEnum.getByCode(scenicConfig.getWatermarkType());
|
ImageWatermarkOperatorEnum type = ImageWatermarkOperatorEnum.getByCode(scenicConfig.getWatermarkType());
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
IStorageAdapter adapter;
|
IStorageAdapter adapter;
|
||||||
@@ -662,8 +667,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
List<SourceWatermarkEntity> watermarkEntityList = sourceMapper.listSourceWatermark(list.stream().map(SourceRespVO::getId).collect(Collectors.toList()), face.getId(), type.getType());
|
List<SourceWatermarkEntity> watermarkEntityList = sourceMapper.listSourceWatermark(list.stream().map(SourceRespVO::getId).collect(Collectors.toList()), face.getId(), type.getType());
|
||||||
File qrcode = new File("qrcode_"+face.getId()+".jpg");
|
File qrcode = new File("qrcode_"+face.getId()+".jpg");
|
||||||
try {
|
try {
|
||||||
String urlLink = WxMpUtil.generateUrlLink(scenicMpConfig.getAppId(), scenicMpConfig.getAppSecret(), "pages/videoSynthesis/index", "scenicId=" + face.getScenicId() + "&faceId=" + face.getId());
|
WxMpUtil.generateUnlimitedWXAQRCode(scenicMpConfig.getAppId(), scenicMpConfig.getAppSecret(), "pages/videoSynthesis/from_face", face.getId().toString(), qrcode);
|
||||||
QrCodeUtil.generate(urlLink + "?cq=", 300, 300, qrcode);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("generateWXQRCode error", e);
|
log.error("generateWXQRCode error", e);
|
||||||
return defaultUrlList;
|
return defaultUrlList;
|
||||||
@@ -733,7 +737,7 @@ public class GoodsServiceImpl implements GoodsService {
|
|||||||
}
|
}
|
||||||
Integer sourceType = query.getSourceType();
|
Integer sourceType = query.getSourceType();
|
||||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||||
sourceReqQuery.setScenicId(query.getScenicId());
|
sourceReqQuery.setScenicId(face.getScenicId());
|
||||||
sourceReqQuery.setIsBuy(query.getIsBuy());
|
sourceReqQuery.setIsBuy(query.getIsBuy());
|
||||||
sourceReqQuery.setMemberId(face.getMemberId());
|
sourceReqQuery.setMemberId(face.getMemberId());
|
||||||
sourceReqQuery.setType(sourceType);
|
sourceReqQuery.setType(sourceType);
|
||||||
|
@@ -36,4 +36,6 @@ public interface FaceService {
|
|||||||
List<ContentPageVO> faceContentList(Long faceId);
|
List<ContentPageVO> faceContentList(Long faceId);
|
||||||
|
|
||||||
ApiResponse<List<ContentPageVO>> contentListUseDefaultFace();
|
ApiResponse<List<ContentPageVO>> contentListUseDefaultFace();
|
||||||
|
|
||||||
|
void bindFace(Long faceId, Long userId);
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +0,0 @@
|
|||||||
package com.ycwl.basic.service.pc;
|
|
||||||
|
|
||||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
|
||||||
import com.ycwl.basic.model.pc.menu.entity.MenuEntity;
|
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author:longbinbin
|
|
||||||
* @Date:2024/12/3 10:40
|
|
||||||
*/
|
|
||||||
public interface MenuService {
|
|
||||||
ApiResponse<List<MenuNode>> list(Integer type);
|
|
||||||
ApiResponse<Integer> add(MenuEntity menu);
|
|
||||||
ApiResponse<Integer> update(MenuEntity menu);
|
|
||||||
ApiResponse<Integer> deleteById(Long id);
|
|
||||||
}
|
|
@@ -4,11 +4,14 @@ import com.github.pagehelper.PageInfo;
|
|||||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||||
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
||||||
|
import com.ycwl.basic.model.pc.role.resp.RolePermissionResp;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface RoleService {
|
public interface RoleService {
|
||||||
|
RolePermissionResp getPermissionByRoleId(Long roleId);
|
||||||
|
|
||||||
ApiResponse<PageInfo<RoleListRespVO>> pageQuery(RoleListReqVO roleListReqVO);
|
ApiResponse<PageInfo<RoleListRespVO>> pageQuery(RoleListReqVO roleListReqVO);
|
||||||
ApiResponse list(RoleListReqVO roleListReqVO);
|
ApiResponse list(RoleListReqVO roleListReqVO);
|
||||||
ApiResponse addOrUpdate(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO);
|
ApiResponse addOrUpdate(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO);
|
||||||
|
@@ -21,4 +21,5 @@ public interface SourceService {
|
|||||||
ApiResponse<Integer> update(SourceEntity source);
|
ApiResponse<Integer> update(SourceEntity source);
|
||||||
|
|
||||||
ApiResponse cutVideo(Long id);
|
ApiResponse cutVideo(Long id);
|
||||||
|
ApiResponse<String> uploadAndUpdateUrl(Long id, org.springframework.web.multipart.MultipartFile file);
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.ycwl.basic.constant.JwtRoleConstant.ADMIN;
|
||||||
import static com.ycwl.basic.constant.PermissionConstant.ROLE_STATUS;
|
import static com.ycwl.basic.constant.PermissionConstant.ROLE_STATUS;
|
||||||
|
|
||||||
|
|
||||||
@@ -56,12 +57,17 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse addOrUpdate(AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO) {
|
public ApiResponse addOrUpdate(AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO) {
|
||||||
|
if (StringUtils.isNotBlank(addOrUpdateAdminUserReqVO.getPassword())) {
|
||||||
addOrUpdateAdminUserReqVO.setPassword(DigestUtil.md5Hex(addOrUpdateAdminUserReqVO.getPassword()));
|
addOrUpdateAdminUserReqVO.setPassword(DigestUtil.md5Hex(addOrUpdateAdminUserReqVO.getPassword()));
|
||||||
|
} else {
|
||||||
|
addOrUpdateAdminUserReqVO.setPassword(null);
|
||||||
|
}
|
||||||
String id = addOrUpdateAdminUserReqVO.getId();
|
String id = addOrUpdateAdminUserReqVO.getId();
|
||||||
if (StringUtils.isBlank(id)) {
|
if (StringUtils.isBlank(id)) {
|
||||||
addOrUpdateAdminUserReqVO.setId(SnowFlakeUtil.getId());
|
addOrUpdateAdminUserReqVO.setId(SnowFlakeUtil.getId());
|
||||||
// String password = addOrUpdateAdminUserReqVO.getPassword();
|
if (StringUtils.isBlank(addOrUpdateAdminUserReqVO.getPassword())) {
|
||||||
// addOrUpdateAdminUserReqVO.setPassword(password);
|
return ApiResponse.fail("密码不能为空");
|
||||||
|
}
|
||||||
int add = adminUserMapper.add(addOrUpdateAdminUserReqVO);
|
int add = adminUserMapper.add(addOrUpdateAdminUserReqVO);
|
||||||
if (add > 0) {
|
if (add > 0) {
|
||||||
return ApiResponse.success(null);
|
return ApiResponse.success(null);
|
||||||
@@ -105,7 +111,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||||||
if (!login.getPassword().equals(DigestUtil.md5Hex(password))) {
|
if (!login.getPassword().equals(DigestUtil.md5Hex(password))) {
|
||||||
return ApiResponse.fail("账号不存在或密码错误");
|
return ApiResponse.fail("账号不存在或密码错误");
|
||||||
}
|
}
|
||||||
String roleId = login.getRoleId();
|
Long roleId = login.getRoleId();
|
||||||
|
|
||||||
Object roleObject = redisTemplate.opsForValue().get(ROLE_STATUS + roleId);
|
Object roleObject = redisTemplate.opsForValue().get(ROLE_STATUS + roleId);
|
||||||
|
|
||||||
@@ -114,27 +120,12 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||||||
throw new RoleStatusException("该角色下的账号已被封禁,请联系管理员");
|
throw new RoleStatusException("该角色下的账号已被封禁,请联系管理员");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<MenuNode> menuById = roleMapper.getMenuById(roleId);
|
|
||||||
List<MenuNode> MenuList = new ArrayList<>();
|
|
||||||
for (MenuNode item : menuById) {
|
|
||||||
if ("-1".equals(item.getParentId())) {
|
|
||||||
MenuList.add(item);
|
|
||||||
}
|
|
||||||
for (MenuNode item2 : menuById) {
|
|
||||||
if (item2.getParentId().equals(item.getId())) {
|
|
||||||
if (item.getChildrenList() == null) {
|
|
||||||
item.setChildrenList(new ArrayList<>());
|
|
||||||
}
|
|
||||||
item.getChildrenList().add(item2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LoginRespVO loginRespVO = new LoginRespVO();
|
LoginRespVO loginRespVO = new LoginRespVO();
|
||||||
String token = jwtTokenUtil.generateToken(new JwtInfo(login.getStaffName(), login.getStaffId(), roleId, login.getAccount(), login.getAccount(), null));
|
String token = jwtTokenUtil.generateToken(new JwtInfo(login.getStaffName(), login.getStaffId(), ADMIN.type, login.getAccount(), login.getAccount(), null), login.getUpdateAt());
|
||||||
loginRespVO.setToken(token);
|
loginRespVO.setToken(token);
|
||||||
loginRespVO.setName(login.getStaffName());
|
loginRespVO.setName(login.getStaffName());
|
||||||
loginRespVO.setTypeName(login.getTypeName());
|
loginRespVO.setTypeName(login.getTypeName());
|
||||||
loginRespVO.setMenuNodeList(MenuList);
|
loginRespVO.setSuperAdmin(Long.valueOf(1L).equals(login.getStaffId()));
|
||||||
return ApiResponse.success(loginRespVO);
|
return ApiResponse.success(loginRespVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,10 +8,7 @@ import com.ycwl.basic.biz.TemplateBiz;
|
|||||||
import com.ycwl.basic.constant.BaseContextHandler;
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
import com.ycwl.basic.enums.StatisticEnum;
|
import com.ycwl.basic.enums.StatisticEnum;
|
||||||
import com.ycwl.basic.exception.BaseException;
|
import com.ycwl.basic.exception.BaseException;
|
||||||
import com.ycwl.basic.facebody.FaceBodyFactory;
|
|
||||||
import com.ycwl.basic.facebody.adapter.AliFaceBodyAdapter;
|
|
||||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||||
import com.ycwl.basic.mapper.FaceSampleMapper;
|
|
||||||
import com.ycwl.basic.mapper.SourceMapper;
|
import com.ycwl.basic.mapper.SourceMapper;
|
||||||
import com.ycwl.basic.mapper.StatisticsMapper;
|
import com.ycwl.basic.mapper.StatisticsMapper;
|
||||||
import com.ycwl.basic.mapper.FaceMapper;
|
import com.ycwl.basic.mapper.FaceMapper;
|
||||||
@@ -21,6 +18,7 @@ import com.ycwl.basic.model.mobile.face.FaceRecognizeResp;
|
|||||||
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
|
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
|
||||||
import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO;
|
import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO;
|
||||||
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
|
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
|
||||||
|
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||||
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
||||||
import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
|
import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
|
||||||
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
||||||
@@ -34,6 +32,7 @@ import com.ycwl.basic.model.pc.task.entity.TaskEntity;
|
|||||||
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
|
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
|
||||||
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
|
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
|
||||||
import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
|
import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
|
||||||
|
import com.ycwl.basic.repository.DeviceRepository;
|
||||||
import com.ycwl.basic.repository.FaceRepository;
|
import com.ycwl.basic.repository.FaceRepository;
|
||||||
import com.ycwl.basic.repository.ScenicRepository;
|
import com.ycwl.basic.repository.ScenicRepository;
|
||||||
import com.ycwl.basic.repository.VideoRepository;
|
import com.ycwl.basic.repository.VideoRepository;
|
||||||
@@ -45,6 +44,7 @@ import com.ycwl.basic.service.task.TaskService;
|
|||||||
import com.ycwl.basic.storage.StorageFactory;
|
import com.ycwl.basic.storage.StorageFactory;
|
||||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||||
import com.ycwl.basic.storage.utils.StorageUtil;
|
import com.ycwl.basic.storage.utils.StorageUtil;
|
||||||
|
import com.ycwl.basic.task.VideoPieceGetter;
|
||||||
import com.ycwl.basic.utils.*;
|
import com.ycwl.basic.utils.*;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -52,11 +52,12 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -99,6 +100,8 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
private VideoTaskRepository videoTaskRepository;
|
private VideoTaskRepository videoTaskRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private TemplateBiz templateBiz;
|
private TemplateBiz templateBiz;
|
||||||
|
@Autowired
|
||||||
|
private DeviceRepository deviceRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<PageInfo<FaceRespVO>> pageQuery(FaceReqQuery faceReqQuery) {
|
public ApiResponse<PageInfo<FaceRespVO>> pageQuery(FaceReqQuery faceReqQuery) {
|
||||||
@@ -280,13 +283,59 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
if (sampleListIds != null && !sampleListIds.isEmpty()) {// 匹配原片:照片
|
if (sampleListIds != null && !sampleListIds.isEmpty()) {// 匹配原片:照片
|
||||||
List<SourceEntity> sourceEntities = sourceMapper.listBySampleIds(sampleListIds);
|
List<SourceEntity> sourceEntities = sourceMapper.listBySampleIds(sampleListIds);
|
||||||
List<MemberSourceEntity> memberSourceEntityList = sourceEntities.stream().map(sourceEntity -> {
|
List<MemberSourceEntity> memberSourceEntityList = sourceEntities.stream().map(sourceEntity -> {
|
||||||
|
DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(sourceEntity.getDeviceId());
|
||||||
MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
|
MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
|
||||||
memberSourceEntity.setScenicId(face.getScenicId());
|
memberSourceEntity.setScenicId(face.getScenicId());
|
||||||
memberSourceEntity.setFaceId(face.getId());
|
memberSourceEntity.setFaceId(face.getId());
|
||||||
memberSourceEntity.setMemberId(face.getMemberId());
|
memberSourceEntity.setMemberId(face.getMemberId());
|
||||||
memberSourceEntity.setSourceId(sourceEntity.getId());
|
memberSourceEntity.setSourceId(sourceEntity.getId());
|
||||||
memberSourceEntity.setType(sourceEntity.getType());
|
memberSourceEntity.setType(sourceEntity.getType());
|
||||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), sourceEntity.getType(), faceEntity.getId());
|
memberSourceEntity.setIsFree(0);
|
||||||
|
if (deviceConfig != null) {
|
||||||
|
if (sourceEntity.getType() == 1) {
|
||||||
|
if (Integer.valueOf(1).equals(deviceConfig.getVideoFree())) {
|
||||||
|
memberSourceEntity.setIsFree(1);
|
||||||
|
}
|
||||||
|
} else if (sourceEntity.getType() == 2) {
|
||||||
|
if (Integer.valueOf(1).equals(deviceConfig.getImageFree())) {
|
||||||
|
memberSourceEntity.setIsFree(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return memberSourceEntity;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
List<Long> freeSourceIds = new ArrayList<>();
|
||||||
|
List<MemberSourceEntity> photoSource = memberSourceEntityList.stream().filter(item -> item.getIsFree() == 0).filter(item -> Integer.valueOf(2).equals(item.getType())).toList();
|
||||||
|
if (isNew) {
|
||||||
|
// 送照片逻辑
|
||||||
|
if (scenicConfig != null && scenicConfig.getPhotoFreeNum() != null && scenicConfig.getPhotoFreeNum() > 0) {
|
||||||
|
if (scenicConfig.getPhotoFreeNum() > photoSource.size()) {
|
||||||
|
freeSourceIds.addAll(photoSource.stream().map(MemberSourceEntity::getSourceId).toList());
|
||||||
|
} else {
|
||||||
|
freeSourceIds.addAll(photoSource.stream().limit(scenicConfig.getPhotoFreeNum()).map(MemberSourceEntity::getSourceId).toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 重新切视频逻辑
|
||||||
|
if (scenicConfig != null && !Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
|
||||||
|
long videoCount = memberSourceEntityList.stream().filter(item -> item.getType().equals(1)).count();
|
||||||
|
long photoCount = memberSourceEntityList.stream().filter(item -> item.getType().equals(2)).count();
|
||||||
|
if (photoCount > videoCount) {
|
||||||
|
VideoPieceGetter.Task task = new VideoPieceGetter.Task();
|
||||||
|
task.faceId = faceId;
|
||||||
|
task.faceSampleIds = sampleListIds;
|
||||||
|
task.templateId = null;
|
||||||
|
task.memberId = face.getMemberId();
|
||||||
|
task.callback = () -> {
|
||||||
|
log.info("task callback: {}", task);
|
||||||
|
};
|
||||||
|
VideoPieceGetter.addTask(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!memberSourceEntityList.isEmpty()) {
|
||||||
|
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), memberSourceEntityList.getFirst().getType(), faceEntity.getId());
|
||||||
|
for (MemberSourceEntity memberSourceEntity : memberSourceEntityList) {
|
||||||
if (isBuy.isBuy()) { // 如果用户买过
|
if (isBuy.isBuy()) { // 如果用户买过
|
||||||
memberSourceEntity.setIsBuy(1);
|
memberSourceEntity.setIsBuy(1);
|
||||||
} else if (isBuy.isFree()) { // 全免费逻辑
|
} else if (isBuy.isFree()) { // 全免费逻辑
|
||||||
@@ -294,16 +343,12 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
} else {
|
} else {
|
||||||
memberSourceEntity.setIsBuy(0);
|
memberSourceEntity.setIsBuy(0);
|
||||||
}
|
}
|
||||||
return memberSourceEntity;
|
if (freeSourceIds.contains(memberSourceEntity.getSourceId())) {
|
||||||
}).collect(Collectors.toList());
|
memberSourceEntity.setIsFree(1);
|
||||||
if (!memberSourceEntityList.isEmpty()) {
|
}
|
||||||
|
}
|
||||||
sourceMapper.addRelations(memberSourceEntityList);
|
sourceMapper.addRelations(memberSourceEntityList);
|
||||||
taskTaskService.autoCreateTaskByFaceId(face.getId());
|
taskTaskService.autoCreateTaskByFaceId(face.getId());
|
||||||
// VideoPieceGetter.Task task = new VideoPieceGetter.Task();
|
|
||||||
// task.faceId = face.getId();
|
|
||||||
// task.faceSampleIds = sampleListIds;
|
|
||||||
// task.memberId = face.getMemberId();
|
|
||||||
// VideoPieceGetter.addTask(task);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return scenicDbSearchResult;
|
return scenicDbSearchResult;
|
||||||
@@ -336,6 +381,7 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
List<MemberVideoEntity> memberVideoEntityList = videoMapper.userFaceTemplateVideo(userId, faceId, contentPageVO.getTemplateId());
|
List<MemberVideoEntity> memberVideoEntityList = videoMapper.userFaceTemplateVideo(userId, faceId, contentPageVO.getTemplateId());
|
||||||
contentPageVO.setGoodsType(0);
|
contentPageVO.setGoodsType(0);
|
||||||
contentPageVO.setContentType(1);
|
contentPageVO.setContentType(1);
|
||||||
|
contentPageVO.setSort(contentPageVO.getSort());
|
||||||
if (!memberVideoEntityList.isEmpty()) {
|
if (!memberVideoEntityList.isEmpty()) {
|
||||||
contentPageVO.setIsBuy(memberVideoEntityList.getFirst().getIsBuy());
|
contentPageVO.setIsBuy(memberVideoEntityList.getFirst().getIsBuy());
|
||||||
contentPageVO.setContentId(memberVideoEntityList.getFirst().getVideoId());
|
contentPageVO.setContentId(memberVideoEntityList.getFirst().getVideoId());
|
||||||
@@ -375,6 +421,8 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
ContentPageVO sourceImageContent = new ContentPageVO();
|
ContentPageVO sourceImageContent = new ContentPageVO();
|
||||||
sourceVideoContent.setName("录像集");
|
sourceVideoContent.setName("录像集");
|
||||||
sourceImageContent.setName("照片集");
|
sourceImageContent.setName("照片集");
|
||||||
|
sourceVideoContent.setSort(9999);
|
||||||
|
sourceImageContent.setSort(9999);
|
||||||
sourceVideoContent.setScenicId(faceRespVO.getScenicId());
|
sourceVideoContent.setScenicId(faceRespVO.getScenicId());
|
||||||
sourceImageContent.setScenicId(faceRespVO.getScenicId());
|
sourceImageContent.setScenicId(faceRespVO.getScenicId());
|
||||||
sourceVideoContent.setGoodsType(1);
|
sourceVideoContent.setGoodsType(1);
|
||||||
@@ -393,12 +441,14 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
} else {
|
} else {
|
||||||
sourceImageContent.setIsBuy(0);
|
sourceImageContent.setIsBuy(0);
|
||||||
}
|
}
|
||||||
List<SourceEntity> sourceEntities = sourceMapper.listImageByFaceRelation(faceRespVO.getMemberId(), faceId);
|
List<MemberSourceEntity> relations = sourceMapper.listByFaceRelation(faceRespVO.getMemberId(), faceId, 2);
|
||||||
if (!sourceEntities.isEmpty()) {
|
if (!relations.isEmpty()) {
|
||||||
sourceImageContent.setLockType(-1);
|
sourceImageContent.setLockType(-1);
|
||||||
} else {
|
} else {
|
||||||
sourceImageContent.setLockType(1);
|
sourceImageContent.setLockType(1);
|
||||||
}
|
}
|
||||||
|
long freeCount = relations.stream().filter(entity -> Integer.valueOf(1).equals(entity.getIsFree())).count();
|
||||||
|
sourceImageContent.setFreeCount((int) freeCount);
|
||||||
contentList.add(sourceImageContent);
|
contentList.add(sourceImageContent);
|
||||||
}
|
}
|
||||||
if (!Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
|
if (!Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
|
||||||
@@ -410,12 +460,14 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
} else {
|
} else {
|
||||||
sourceVideoContent.setIsBuy(0);
|
sourceVideoContent.setIsBuy(0);
|
||||||
}
|
}
|
||||||
List<SourceEntity> sourceEntities = sourceMapper.listVideoByFaceRelation(faceRespVO.getMemberId(), faceId);
|
List<MemberSourceEntity> relations = sourceMapper.listByFaceRelation(faceRespVO.getMemberId(), faceId, 1);
|
||||||
if (!sourceEntities.isEmpty()) {
|
if (!relations.isEmpty()) {
|
||||||
sourceVideoContent.setLockType(-1);
|
sourceVideoContent.setLockType(-1);
|
||||||
} else {
|
} else {
|
||||||
sourceVideoContent.setLockType(1);
|
sourceVideoContent.setLockType(1);
|
||||||
}
|
}
|
||||||
|
long freeCount = relations.stream().filter(entity -> Integer.valueOf(1).equals(entity.getIsFree())).count();
|
||||||
|
sourceVideoContent.setFreeCount((int) freeCount);
|
||||||
contentList.add(sourceVideoContent);
|
contentList.add(sourceVideoContent);
|
||||||
}
|
}
|
||||||
sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).forEach((type, list) -> {
|
sourceList.stream().collect(Collectors.groupingBy(SourceRespVO::getType)).forEach((type, list) -> {
|
||||||
@@ -440,5 +492,10 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
return ApiResponse.success(contentPageVOS);
|
return ApiResponse.success(contentPageVOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindFace(Long faceId, Long userId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,78 +0,0 @@
|
|||||||
package com.ycwl.basic.service.pc.impl;
|
|
||||||
|
|
||||||
import com.ycwl.basic.mapper.MenuMapper;
|
|
||||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
|
||||||
import com.ycwl.basic.model.pc.menu.entity.MenuEntity;
|
|
||||||
import com.ycwl.basic.service.pc.MenuService;
|
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
|
||||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author:longbinbin
|
|
||||||
* @Date:2024/12/3 10:16
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class MenuServiceImpl implements MenuService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MenuMapper menuMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<List<MenuNode>> list(Integer type) {
|
|
||||||
// if(type==null){
|
|
||||||
// type=1;
|
|
||||||
// }
|
|
||||||
List<MenuNode> listByType = menuMapper.getListByType(type);
|
|
||||||
List<MenuNode> MenuList = new ArrayList<>();
|
|
||||||
for (MenuNode item :listByType) {
|
|
||||||
if ("-1".equals(item.getParentId())) {
|
|
||||||
MenuList.add(item);
|
|
||||||
}
|
|
||||||
for (MenuNode item2 : listByType) {
|
|
||||||
if (item2.getParentId().equals(item.getId())) {
|
|
||||||
if (item.getChildrenList() == null) {
|
|
||||||
item.setChildrenList(new ArrayList<>());
|
|
||||||
}
|
|
||||||
item.getChildrenList().add(item2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ApiResponse.success(MenuList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<Integer> add(MenuEntity menu) {
|
|
||||||
menu.setId(SnowFlakeUtil.getId());
|
|
||||||
int add = menuMapper.add(menu);
|
|
||||||
if(add>0){
|
|
||||||
return ApiResponse.success(add);
|
|
||||||
}else {
|
|
||||||
return ApiResponse.fail("添加失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<Integer> update(MenuEntity menu) {
|
|
||||||
int update = menuMapper.update(menu);
|
|
||||||
if(update>0){
|
|
||||||
return ApiResponse.success(update);
|
|
||||||
}else {
|
|
||||||
return ApiResponse.fail("更新失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<Integer> deleteById(Long id) {
|
|
||||||
int deleteById = menuMapper.deleteById(id);
|
|
||||||
if(deleteById>0){
|
|
||||||
return ApiResponse.success(deleteById);
|
|
||||||
}else {
|
|
||||||
return ApiResponse.fail("删除失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,6 +8,7 @@ import com.ycwl.basic.model.pc.menu.MenuNode;
|
|||||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||||
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
||||||
|
import com.ycwl.basic.model.pc.role.resp.RolePermissionResp;
|
||||||
import com.ycwl.basic.service.pc.RoleService;
|
import com.ycwl.basic.service.pc.RoleService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||||
@@ -34,6 +35,11 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
RedisTemplate redisTemplate;
|
RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RolePermissionResp getPermissionByRoleId(Long roleId) {
|
||||||
|
return menuMapper.getPermissionByRoleId(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<PageInfo<RoleListRespVO>> pageQuery(RoleListReqVO roleListReqVO) {
|
public ApiResponse<PageInfo<RoleListRespVO>> pageQuery(RoleListReqVO roleListReqVO) {
|
||||||
PageHelper.startPage(roleListReqVO.getPageNum(),roleListReqVO.getPageSize());
|
PageHelper.startPage(roleListReqVO.getPageNum(),roleListReqVO.getPageSize());
|
||||||
@@ -55,23 +61,22 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse addOrUpdate(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO) {
|
public ApiResponse addOrUpdate(AddOrUpdateRoleReqVO vo) {
|
||||||
String id = addOrUpdateRoleReqVO.getId();
|
String id = vo.getId();
|
||||||
if(StringUtils.isBlank(id)){
|
if(StringUtils.isBlank(id)){
|
||||||
String roleId = SnowFlakeUtil.getId();
|
String roleId = SnowFlakeUtil.getId();
|
||||||
addOrUpdateRoleReqVO.setId(roleId);
|
vo.setId(roleId);
|
||||||
if(roleMapper.add(addOrUpdateRoleReqVO)>0){
|
if(roleMapper.add(vo)>0){
|
||||||
if (addOrUpdateRoleReqVO.getMenuIdList() != null && !addOrUpdateRoleReqVO.getMenuIdList().isEmpty()) {
|
String menuStr = StringUtils.join(vo.getMenus(), ",");
|
||||||
menuMapper.addRoleMenu(roleId, addOrUpdateRoleReqVO.getMenuIdList());
|
String permStr = StringUtils.join(vo.getPermissions(), ",");
|
||||||
}
|
menuMapper.addRoleMenu(roleId, menuStr, permStr);
|
||||||
return ApiResponse.success(null);
|
return ApiResponse.success(null);
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
if(roleMapper.update(addOrUpdateRoleReqVO)>0){
|
if(roleMapper.update(vo)>0){
|
||||||
menuMapper.deleteRoleMenuByRoleId(addOrUpdateRoleReqVO.getId());
|
String menuStr = StringUtils.join(vo.getMenus(), ",");
|
||||||
if (addOrUpdateRoleReqVO.getMenuIdList() != null && !addOrUpdateRoleReqVO.getMenuIdList().isEmpty()) {
|
String permStr = StringUtils.join(vo.getPermissions(), ",");
|
||||||
menuMapper.addRoleMenu(addOrUpdateRoleReqVO.getId(), addOrUpdateRoleReqVO.getMenuIdList());
|
menuMapper.addRoleMenu(id, menuStr, permStr);
|
||||||
}
|
|
||||||
return ApiResponse.success(null);
|
return ApiResponse.success(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -145,6 +145,11 @@ public class ScenicServiceImpl implements ScenicService {
|
|||||||
int i = scenicMapper.update(scenicUpdateReq);
|
int i = scenicMapper.update(scenicUpdateReq);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
scenicRepository.clearCache(scenicUpdateReq.getId());
|
scenicRepository.clearCache(scenicUpdateReq.getId());
|
||||||
|
scenicFaceBodyAdapterMap.remove(scenicUpdateReq.getId());
|
||||||
|
scenicStorageAdapterMap.remove(scenicUpdateReq.getId());
|
||||||
|
scenicTmpStorageAdapterMap.remove(scenicUpdateReq.getId());
|
||||||
|
scenicLocalStorageAdapterMap.remove(scenicUpdateReq.getId());
|
||||||
|
scenicPayAdapterMap.remove(scenicUpdateReq.getId());
|
||||||
return ApiResponse.success(true);
|
return ApiResponse.success(true);
|
||||||
}else {
|
}else {
|
||||||
return ApiResponse.fail("景区修改失败");
|
return ApiResponse.fail("景区修改失败");
|
||||||
@@ -157,6 +162,11 @@ public class ScenicServiceImpl implements ScenicService {
|
|||||||
int i = scenicMapper.updateStatus(id);
|
int i = scenicMapper.updateStatus(id);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
scenicRepository.clearCache(id);
|
scenicRepository.clearCache(id);
|
||||||
|
scenicFaceBodyAdapterMap.remove(id);
|
||||||
|
scenicStorageAdapterMap.remove(id);
|
||||||
|
scenicTmpStorageAdapterMap.remove(id);
|
||||||
|
scenicLocalStorageAdapterMap.remove(id);
|
||||||
|
scenicPayAdapterMap.remove(id);
|
||||||
return ApiResponse.success(true);
|
return ApiResponse.success(true);
|
||||||
}else {
|
}else {
|
||||||
return ApiResponse.fail("景区状态修改失败");
|
return ApiResponse.fail("景区状态修改失败");
|
||||||
@@ -182,6 +192,11 @@ public class ScenicServiceImpl implements ScenicService {
|
|||||||
int i = scenicMapper.updateConfigById(scenicConfig);
|
int i = scenicMapper.updateConfigById(scenicConfig);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
scenicRepository.clearCache(scenicConfig.getScenicId());
|
scenicRepository.clearCache(scenicConfig.getScenicId());
|
||||||
|
scenicFaceBodyAdapterMap.remove(scenicConfig.getScenicId());
|
||||||
|
scenicStorageAdapterMap.remove(scenicConfig.getScenicId());
|
||||||
|
scenicTmpStorageAdapterMap.remove(scenicConfig.getScenicId());
|
||||||
|
scenicLocalStorageAdapterMap.remove(scenicConfig.getScenicId());
|
||||||
|
scenicPayAdapterMap.remove(scenicConfig.getScenicId());
|
||||||
return ApiResponse.success(true);
|
return ApiResponse.success(true);
|
||||||
}else {
|
}else {
|
||||||
return ApiResponse.fail("景区配置修改失败");
|
return ApiResponse.fail("景区配置修改失败");
|
||||||
|
@@ -7,13 +7,17 @@ import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
|||||||
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
|
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
|
||||||
import com.ycwl.basic.model.pc.source.resp.SourceRespVO;
|
import com.ycwl.basic.model.pc.source.resp.SourceRespVO;
|
||||||
import com.ycwl.basic.repository.SourceRepository;
|
import com.ycwl.basic.repository.SourceRepository;
|
||||||
|
import com.ycwl.basic.service.pc.ScenicService;
|
||||||
import com.ycwl.basic.service.pc.SourceService;
|
import com.ycwl.basic.service.pc.SourceService;
|
||||||
|
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||||
import com.ycwl.basic.task.VideoPieceGetter;
|
import com.ycwl.basic.task.VideoPieceGetter;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import com.ycwl.basic.storage.StorageFactory;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@@ -30,6 +34,8 @@ public class SourceServiceImpl implements SourceService {
|
|||||||
private SourceMapper sourceMapper;
|
private SourceMapper sourceMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SourceRepository sourceRepository;
|
private SourceRepository sourceRepository;
|
||||||
|
@Autowired
|
||||||
|
private ScenicService scenicService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<PageInfo<SourceRespVO>> pageQuery(SourceReqQuery sourceReqQuery) {
|
public ApiResponse<PageInfo<SourceRespVO>> pageQuery(SourceReqQuery sourceReqQuery) {
|
||||||
@@ -137,4 +143,29 @@ public class SourceServiceImpl implements SourceService {
|
|||||||
}
|
}
|
||||||
return ApiResponse.success("任务已下发");
|
return ApiResponse.success("任务已下发");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<String> uploadAndUpdateUrl(Long id, MultipartFile file) {
|
||||||
|
SourceRespVO source = sourceMapper.getById(id);
|
||||||
|
if (source == null) {
|
||||||
|
return ApiResponse.fail("该素材不存在");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
IStorageAdapter adapter = scenicService.getScenicStorageAdapter(source.getScenicId());
|
||||||
|
String uploadedUrl = adapter.uploadFile(file, "source", String.valueOf(id));
|
||||||
|
|
||||||
|
SourceEntity sourceUpd = new SourceEntity();
|
||||||
|
sourceUpd.setId(id);
|
||||||
|
sourceUpd.setUrl(uploadedUrl);
|
||||||
|
|
||||||
|
int updateResult = sourceMapper.update(sourceUpd);
|
||||||
|
if (updateResult > 0) {
|
||||||
|
return ApiResponse.success(uploadedUrl);
|
||||||
|
} else {
|
||||||
|
return ApiResponse.fail("更新URL失败");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponse.fail("文件上传失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -87,13 +87,13 @@ public class TaskFaceServiceImpl implements TaskFaceService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchFaceRespVo searchFace(Long faceId) {
|
public SearchFaceRespVo searchFace(Long faceId) {
|
||||||
FaceRespVO faceRespVO = faceMapper.getById(faceId);
|
FaceRespVO face = faceMapper.getById(faceId);
|
||||||
if (faceRespVO == null) {
|
if (face == null) {
|
||||||
SearchFaceRespVo vo = new SearchFaceRespVo();
|
SearchFaceRespVo vo = new SearchFaceRespVo();
|
||||||
vo.setSampleListIds(new ArrayList<>());
|
vo.setSampleListIds(new ArrayList<>());
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
Long scenicId = faceRespVO.getScenicId();
|
Long scenicId = face.getScenicId();
|
||||||
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
|
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
|
||||||
IFaceBodyAdapter faceBodyAdapter;
|
IFaceBodyAdapter faceBodyAdapter;
|
||||||
if (scenicConfig != null && scenicConfig.getFaceType() != null) {
|
if (scenicConfig != null && scenicConfig.getFaceType() != null) {
|
||||||
@@ -102,7 +102,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
|
|||||||
} else {
|
} else {
|
||||||
faceBodyAdapter = FaceBodyFactory.use();
|
faceBodyAdapter = FaceBodyFactory.use();
|
||||||
}
|
}
|
||||||
SearchFaceRespVo respVo = searchFace(faceBodyAdapter, scenicId.toString(), faceRespVO.getFaceUrl(), "系统定时任务检索");
|
SearchFaceRespVo respVo = searchFace(faceBodyAdapter, scenicId.toString(), face.getFaceUrl(), "系统定时任务检索");
|
||||||
if (respVo != null) {
|
if (respVo != null) {
|
||||||
FaceEntity faceEntity = new FaceEntity();
|
FaceEntity faceEntity = new FaceEntity();
|
||||||
faceEntity.setId(faceId);
|
faceEntity.setId(faceId);
|
||||||
@@ -120,17 +120,9 @@ public class TaskFaceServiceImpl implements TaskFaceService {
|
|||||||
MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
|
MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
|
||||||
memberSourceEntity.setScenicId(scenicId);
|
memberSourceEntity.setScenicId(scenicId);
|
||||||
memberSourceEntity.setFaceId(faceEntity.getId());
|
memberSourceEntity.setFaceId(faceEntity.getId());
|
||||||
memberSourceEntity.setMemberId(faceRespVO.getMemberId());
|
memberSourceEntity.setMemberId(face.getMemberId());
|
||||||
memberSourceEntity.setSourceId(sourceEntity.getId());
|
memberSourceEntity.setSourceId(sourceEntity.getId());
|
||||||
memberSourceEntity.setType(sourceEntity.getType());
|
memberSourceEntity.setType(sourceEntity.getType());
|
||||||
IsBuyRespVO isBuy = orderBiz.isBuy(faceRespVO.getMemberId(), scenicId, sourceEntity.getType(), sourceEntity.getId());
|
|
||||||
if (isBuy.isBuy()) { // 如果用户买过
|
|
||||||
memberSourceEntity.setIsBuy(1);
|
|
||||||
} else if (isBuy.isFree()) { // 全免费逻辑
|
|
||||||
memberSourceEntity.setIsBuy(1);
|
|
||||||
} else {
|
|
||||||
memberSourceEntity.setIsBuy(0);
|
|
||||||
}
|
|
||||||
memberSourceEntity.setIsFree(0);
|
memberSourceEntity.setIsFree(0);
|
||||||
if (deviceConfig != null) {
|
if (deviceConfig != null) {
|
||||||
if (sourceEntity.getType() == 1) {
|
if (sourceEntity.getType() == 1) {
|
||||||
@@ -146,11 +138,21 @@ public class TaskFaceServiceImpl implements TaskFaceService {
|
|||||||
return memberSourceEntity;
|
return memberSourceEntity;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
if (!memberSourceEntityList.isEmpty()) {
|
if (!memberSourceEntityList.isEmpty()) {
|
||||||
|
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), memberSourceEntityList.getFirst().getType(), faceEntity.getId());
|
||||||
|
for (MemberSourceEntity memberSourceEntity : memberSourceEntityList) {
|
||||||
|
if (isBuy.isBuy()) { // 如果用户买过
|
||||||
|
memberSourceEntity.setIsBuy(1);
|
||||||
|
} else if (isBuy.isFree()) { // 全免费逻辑
|
||||||
|
memberSourceEntity.setIsBuy(1);
|
||||||
|
} else {
|
||||||
|
memberSourceEntity.setIsBuy(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
sourceMapper.addRelations(memberSourceEntityList);
|
sourceMapper.addRelations(memberSourceEntityList);
|
||||||
VideoPieceGetter.Task task = new VideoPieceGetter.Task();
|
VideoPieceGetter.Task task = new VideoPieceGetter.Task();
|
||||||
task.faceId = faceEntity.getId();
|
task.faceId = faceEntity.getId();
|
||||||
task.faceSampleIds = sampleListIds;
|
task.faceSampleIds = sampleListIds;
|
||||||
task.memberId = faceRespVO.getMemberId();
|
task.memberId = face.getMemberId();
|
||||||
VideoPieceGetter.addTask(task);
|
VideoPieceGetter.addTask(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -175,6 +175,7 @@ public class TaskTaskServiceImpl implements TaskService {
|
|||||||
taskList.forEach(task -> {
|
taskList.forEach(task -> {
|
||||||
taskMapper.assignToWorker(task.getId(), worker.getId());
|
taskMapper.assignToWorker(task.getId(), worker.getId());
|
||||||
videoTaskRepository.clearTaskCache(task.getId());
|
videoTaskRepository.clearTaskCache(task.getId());
|
||||||
|
repository.clearCache(worker.getId());
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@@ -445,6 +446,10 @@ public class TaskTaskServiceImpl implements TaskService {
|
|||||||
.peek(item -> item.setUrl(item.getVideoUrl()))
|
.peek(item -> item.setUrl(item.getVideoUrl()))
|
||||||
.filter(item -> {
|
.filter(item -> {
|
||||||
DeviceEntity device = deviceRepository.getDevice(item.getDeviceId());
|
DeviceEntity device = deviceRepository.getDevice(item.getDeviceId());
|
||||||
|
if (device == null) {
|
||||||
|
log.info("task callback: deviceId:{} is not exist", item.getDeviceId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return Integer.valueOf(1).equals(device.getStatus());
|
return Integer.valueOf(1).equals(device.getStatus());
|
||||||
})
|
})
|
||||||
.filter(item -> item.getDeviceId() != null) // 添加对 deviceId 为 null 的检查
|
.filter(item -> item.getDeviceId() != null) // 添加对 deviceId 为 null 的检查
|
||||||
|
@@ -33,25 +33,37 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
final public class AliOssAdapter extends AStorageAdapter {
|
final public class AliOssAdapter extends AStorageAdapter {
|
||||||
private AliOssStorageConfig config;
|
private volatile AliOssStorageConfig config;
|
||||||
|
private volatile OSS ossClient;
|
||||||
|
private final Object clientLock = new Object();
|
||||||
|
private final Object configLock = new Object();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String identity() {
|
public String identity() {
|
||||||
return config.identity();
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
return "ALI_OSS_UNCONFIGURED";
|
||||||
|
}
|
||||||
|
return currentConfig.identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadConfig(Map<String, String> _config) {
|
public void loadConfig(Map<String, String> _config) {
|
||||||
AliOssStorageConfig config = new AliOssStorageConfig();
|
AliOssStorageConfig newConfig = new AliOssStorageConfig();
|
||||||
config.setAccessKeyId(_config.get("accessKeyId"));
|
newConfig.setAccessKeyId(_config.get("accessKeyId"));
|
||||||
config.setAccessKeySecret(_config.get("accessKeySecret"));
|
newConfig.setAccessKeySecret(_config.get("accessKeySecret"));
|
||||||
config.setBucketName(_config.get("bucketName"));
|
newConfig.setBucketName(_config.get("bucketName"));
|
||||||
config.setEndpoint(_config.get("endpoint"));
|
newConfig.setEndpoint(_config.get("endpoint"));
|
||||||
config.setRegion(_config.get("region"));
|
newConfig.setRegion(_config.get("region"));
|
||||||
config.setUrl(_config.get("url"));
|
newConfig.setUrl(_config.get("url"));
|
||||||
config.setPrefix(_config.get("prefix"));
|
newConfig.setPrefix(_config.get("prefix"));
|
||||||
config.checkEverythingOK();
|
newConfig.checkEverythingOK();
|
||||||
this.config = config;
|
|
||||||
|
synchronized (configLock) {
|
||||||
|
this.config = newConfig;
|
||||||
|
// 配置更新后,需要重置客户端连接
|
||||||
|
resetClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,11 +71,15 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
if (config == null) {
|
if (config == null) {
|
||||||
throw new StorageConfigException("配置为空");
|
throw new StorageConfigException("配置为空");
|
||||||
}
|
}
|
||||||
if (config instanceof AliOssStorageConfig) {
|
if (!(config instanceof AliOssStorageConfig)) {
|
||||||
this.config = (AliOssStorageConfig) config;
|
|
||||||
} else {
|
|
||||||
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
|
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (configLock) {
|
||||||
|
this.config = (AliOssStorageConfig) config;
|
||||||
|
// 配置更新后,需要重置客户端连接
|
||||||
|
resetClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,12 +91,25 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
try (OSSWrapper wrapper = getOssClient()) {
|
try (OSSWrapper wrapper = getOssClient()) {
|
||||||
OSS ossClient = wrapper.getOSSClient();
|
OSS ossClient = wrapper.getOSSClient();
|
||||||
ObjectMetadata metadata = new ObjectMetadata();
|
ObjectMetadata metadata = new ObjectMetadata();
|
||||||
metadata.setContentLength(inputStream.available());
|
|
||||||
|
// 读取完整内容并计算实际长度
|
||||||
|
byte[] bytes = inputStream.readAllBytes();
|
||||||
|
metadata.setContentLength(bytes.length);
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(contentType)) {
|
if (StringUtils.isNotBlank(contentType)) {
|
||||||
metadata.setContentType(contentType);
|
metadata.setContentType(contentType);
|
||||||
}
|
}
|
||||||
PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), fullPath, inputStream);
|
|
||||||
|
// 使用字节数组创建新的 InputStream
|
||||||
|
try (InputStream byteInputStream = new java.io.ByteArrayInputStream(bytes)) {
|
||||||
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
PutObjectRequest putObjectRequest = new PutObjectRequest(currentConfig.getBucketName(), fullPath, byteInputStream, metadata);
|
||||||
ossClient.putObject(putObjectRequest);
|
ossClient.putObject(putObjectRequest);
|
||||||
|
}
|
||||||
|
|
||||||
return getUrl(path);
|
return getUrl(path);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new UploadFileFailedException("上传文件失败:" + e.getMessage());
|
throw new UploadFileFailedException("上传文件失败:" + e.getMessage());
|
||||||
@@ -92,7 +121,11 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
public boolean deleteFile(String... path) {
|
public boolean deleteFile(String... path) {
|
||||||
try (OSSWrapper wrapper = getOssClient()) {
|
try (OSSWrapper wrapper = getOssClient()) {
|
||||||
OSS ossClient = wrapper.getOSSClient();
|
OSS ossClient = wrapper.getOSSClient();
|
||||||
ossClient.deleteObject(config.getBucketName(), buildPath(path));
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ossClient.deleteObject(currentConfig.getBucketName(), buildPath(path));
|
||||||
return true;
|
return true;
|
||||||
} catch (ClientException e) {
|
} catch (ClientException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -101,14 +134,22 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(String... path) {
|
public String getUrl(String... path) {
|
||||||
return config.getUrl() + "/" + buildPath(path);
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
return currentConfig.getUrl() + "/" + buildPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrlForDownload(Date expireDate, String... path) {
|
public String getUrlForDownload(Date expireDate, String... path) {
|
||||||
try (OSSWrapper wrapper = getOssClient()) {
|
try (OSSWrapper wrapper = getOssClient()) {
|
||||||
OSS ossClient = wrapper.getOSSClient();
|
OSS ossClient = wrapper.getOSSClient();
|
||||||
URL url = ossClient.generatePresignedUrl(config.getBucketName(), buildPath(path), expireDate, HttpMethod.GET);
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
URL url = ossClient.generatePresignedUrl(currentConfig.getBucketName(), buildPath(path), expireDate, HttpMethod.GET);
|
||||||
return url.toString();
|
return url.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,7 +158,11 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
public String getUrlForUpload(Date expireDate, String contentType, String... path) {
|
public String getUrlForUpload(Date expireDate, String contentType, String... path) {
|
||||||
try (OSSWrapper wrapper = getOssClient()) {
|
try (OSSWrapper wrapper = getOssClient()) {
|
||||||
OSS ossClient = wrapper.getOSSClient();
|
OSS ossClient = wrapper.getOSSClient();
|
||||||
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(config.getBucketName(), buildPath(path), HttpMethod.PUT);
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(currentConfig.getBucketName(), buildPath(path), HttpMethod.PUT);
|
||||||
if (StringUtils.isNotBlank(contentType)) {
|
if (StringUtils.isNotBlank(contentType)) {
|
||||||
request.setContentType(contentType);
|
request.setContentType(contentType);
|
||||||
}
|
}
|
||||||
@@ -129,7 +174,11 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<StorageFileObject> listDir(String... path) {
|
public List<StorageFileObject> listDir(String... path) {
|
||||||
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName());
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(currentConfig.getBucketName());
|
||||||
listObjectsV2Request.setPrefix(buildPath(path) + "/");
|
listObjectsV2Request.setPrefix(buildPath(path) + "/");
|
||||||
listObjectsV2Request.setMaxKeys(1000);
|
listObjectsV2Request.setMaxKeys(1000);
|
||||||
boolean isTruncated = true;
|
boolean isTruncated = true;
|
||||||
@@ -180,7 +229,11 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
}
|
}
|
||||||
List<StorageFileObject> subList = objectList.subList(idx, idx + batchSize);
|
List<StorageFileObject> subList = objectList.subList(idx, idx + batchSize);
|
||||||
idx += batchSize;
|
idx += batchSize;
|
||||||
DeleteObjectsRequest request = new DeleteObjectsRequest(config.getBucketName());
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DeleteObjectsRequest request = new DeleteObjectsRequest(currentConfig.getBucketName());
|
||||||
request.setKeys(subList.stream().map(StorageFileObject::getFullPath).collect(Collectors.toList()));
|
request.setKeys(subList.stream().map(StorageFileObject::getFullPath).collect(Collectors.toList()));
|
||||||
try {
|
try {
|
||||||
ossClient.deleteObjects(request);
|
ossClient.deleteObjects(request);
|
||||||
@@ -208,7 +261,11 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
public boolean setAcl(StorageAcl acl, String... path) {
|
public boolean setAcl(StorageAcl acl, String... path) {
|
||||||
try (OSSWrapper wrapper = getOssClient()) {
|
try (OSSWrapper wrapper = getOssClient()) {
|
||||||
OSS ossClient = wrapper.getOSSClient();
|
OSS ossClient = wrapper.getOSSClient();
|
||||||
ossClient.setObjectAcl(config.getBucketName(), buildPath(path), convertAcl(acl));
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ossClient.setObjectAcl(currentConfig.getBucketName(), buildPath(path), convertAcl(acl));
|
||||||
return true;
|
return true;
|
||||||
} catch (OSSException e) {
|
} catch (OSSException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -219,32 +276,85 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
public boolean isExists(String ...path) {
|
public boolean isExists(String ...path) {
|
||||||
try (OSSWrapper wrapper = getOssClient()) {
|
try (OSSWrapper wrapper = getOssClient()) {
|
||||||
OSS ossClient = wrapper.getOSSClient();
|
OSS ossClient = wrapper.getOSSClient();
|
||||||
return ossClient.doesObjectExist(config.getBucketName(), buildPath(path));
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ossClient.doesObjectExist(currentConfig.getBucketName(), buildPath(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private OSSWrapper getOssClient() {
|
private OSSWrapper getOssClient() {
|
||||||
OSS ossClient = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
return new OSSWrapper(ossClient);
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ossClient == null) {
|
||||||
|
synchronized (clientLock) {
|
||||||
|
if (ossClient == null) {
|
||||||
|
// 在同步块内再次检查配置,确保配置一致性
|
||||||
|
currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
ossClient = new OSSClientBuilder().build(
|
||||||
|
currentConfig.getEndpoint(),
|
||||||
|
currentConfig.getAccessKeyId(),
|
||||||
|
currentConfig.getAccessKeySecret()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new OSSWrapper(ossClient, false); // false 表示不自动关闭共享客户端
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置客户端连接(配置更新时调用)
|
||||||
|
private void resetClient() {
|
||||||
|
synchronized (clientLock) {
|
||||||
|
if (ossClient != null) {
|
||||||
|
ossClient.shutdown();
|
||||||
|
ossClient = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动关闭客户端的方法,用于适配器销毁时
|
||||||
|
public void shutdown() {
|
||||||
|
synchronized (clientLock) {
|
||||||
|
if (ossClient != null) {
|
||||||
|
ossClient.shutdown();
|
||||||
|
ossClient = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildPath(String ...paths) {
|
private String buildPath(String ...paths) {
|
||||||
if (StringUtils.isNotBlank(config.getPrefix())) {
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
return StorageUtil.joinPath(config.getPrefix(), paths);
|
if (currentConfig != null && StringUtils.isNotBlank(currentConfig.getPrefix())) {
|
||||||
|
return StorageUtil.joinPath(currentConfig.getPrefix(), paths);
|
||||||
} else {
|
} else {
|
||||||
return StorageUtil.joinPath(paths);
|
return StorageUtil.joinPath(paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRelativePath(String path) {
|
private String getRelativePath(String path) {
|
||||||
return StorageUtil.getRelativePath(path, config.getPrefix());
|
AliOssStorageConfig currentConfig = this.config;
|
||||||
|
String prefix = currentConfig != null ? currentConfig.getPrefix() : null;
|
||||||
|
return StorageUtil.getRelativePath(path, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OSSWrapper implements AutoCloseable {
|
public static class OSSWrapper implements AutoCloseable {
|
||||||
private final OSS ossClient;
|
private final OSS ossClient;
|
||||||
|
private final boolean autoClose;
|
||||||
|
|
||||||
public OSSWrapper(OSS ossClient) {
|
public OSSWrapper(OSS ossClient) {
|
||||||
|
this(ossClient, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OSSWrapper(OSS ossClient, boolean autoClose) {
|
||||||
this.ossClient = ossClient;
|
this.ossClient = ossClient;
|
||||||
|
this.autoClose = autoClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提供对原始对象的方法访问
|
// 提供对原始对象的方法访问
|
||||||
@@ -254,8 +364,10 @@ final public class AliOssAdapter extends AStorageAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
// 在此处实现资源关闭逻辑(如调用 OSS 的关闭方法)
|
// 只有非共享客户端才自动关闭
|
||||||
ossClient.shutdown(); // 假设 OSS 提供 shutdown 方法关闭资源
|
if (autoClose && ossClient != null) {
|
||||||
|
ossClient.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,25 +26,37 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class AwsOssAdapter extends AStorageAdapter {
|
public class AwsOssAdapter extends AStorageAdapter {
|
||||||
private AwsOssStorageConfig config;
|
private volatile AwsOssStorageConfig config;
|
||||||
|
private volatile AmazonS3Client s3Client;
|
||||||
|
private final Object clientLock = new Object();
|
||||||
|
private final Object configLock = new Object();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String identity() {
|
public String identity() {
|
||||||
return config.identity();
|
AwsOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
return "AWS_OSS_UNCONFIGURED";
|
||||||
|
}
|
||||||
|
return currentConfig.identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadConfig(Map<String, String> _config) {
|
public void loadConfig(Map<String, String> _config) {
|
||||||
AwsOssStorageConfig config = new AwsOssStorageConfig();
|
AwsOssStorageConfig newConfig = new AwsOssStorageConfig();
|
||||||
config.setAccessKeyId(_config.get("accessKeyId"));
|
newConfig.setAccessKeyId(_config.get("accessKeyId"));
|
||||||
config.setAccessKeySecret(_config.get("accessKeySecret"));
|
newConfig.setAccessKeySecret(_config.get("accessKeySecret"));
|
||||||
config.setBucketName(_config.get("bucketName"));
|
newConfig.setBucketName(_config.get("bucketName"));
|
||||||
config.setEndpoint(_config.get("endpoint"));
|
newConfig.setEndpoint(_config.get("endpoint"));
|
||||||
config.setRegion(_config.get("region"));
|
newConfig.setRegion(_config.get("region"));
|
||||||
config.setUrl(_config.get("url"));
|
newConfig.setUrl(_config.get("url"));
|
||||||
config.setPrefix(_config.get("prefix"));
|
newConfig.setPrefix(_config.get("prefix"));
|
||||||
config.checkEverythingOK();
|
newConfig.checkEverythingOK();
|
||||||
this.config = config;
|
|
||||||
|
synchronized (configLock) {
|
||||||
|
this.config = newConfig;
|
||||||
|
// 配置更新后,需要重置客户端连接
|
||||||
|
resetClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,11 +64,15 @@ public class AwsOssAdapter extends AStorageAdapter {
|
|||||||
if (config == null) {
|
if (config == null) {
|
||||||
throw new StorageConfigException("配置为空");
|
throw new StorageConfigException("配置为空");
|
||||||
}
|
}
|
||||||
if (config instanceof AwsOssStorageConfig) {
|
if (!(config instanceof AwsOssStorageConfig)) {
|
||||||
this.config = (AwsOssStorageConfig) config;
|
|
||||||
} else {
|
|
||||||
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
|
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (configLock) {
|
||||||
|
this.config = (AwsOssStorageConfig) config;
|
||||||
|
// 配置更新后,需要重置客户端连接
|
||||||
|
resetClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -68,13 +84,22 @@ public class AwsOssAdapter extends AStorageAdapter {
|
|||||||
try (S3Wrapper wrapper = getS3Client()) {
|
try (S3Wrapper wrapper = getS3Client()) {
|
||||||
AmazonS3Client s3Client = wrapper.s3Client();
|
AmazonS3Client s3Client = wrapper.s3Client();
|
||||||
ObjectMetadata metadata = new ObjectMetadata();
|
ObjectMetadata metadata = new ObjectMetadata();
|
||||||
metadata.setContentLength(inputStream.available());
|
|
||||||
|
// 读取完整内容并计算实际长度
|
||||||
|
byte[] bytes = inputStream.readAllBytes();
|
||||||
|
metadata.setContentLength(bytes.length);
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(contentType)) {
|
if (StringUtils.isNotBlank(contentType)) {
|
||||||
metadata.setContentType(contentType);
|
metadata.setContentType(contentType);
|
||||||
}
|
}
|
||||||
PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), fullPath, inputStream, metadata);
|
|
||||||
|
// 使用字节数组创建新的 InputStream
|
||||||
|
try (InputStream byteInputStream = new java.io.ByteArrayInputStream(bytes)) {
|
||||||
|
PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), fullPath, byteInputStream, metadata);
|
||||||
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead); // 设置访问权限,让所有用户都允许访问
|
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead); // 设置访问权限,让所有用户都允许访问
|
||||||
s3Client.putObject(putObjectRequest);
|
s3Client.putObject(putObjectRequest);
|
||||||
|
}
|
||||||
|
|
||||||
return getUrl(path);
|
return getUrl(path);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new UploadFileFailedException("上传文件失败:" + e.getMessage());
|
throw new UploadFileFailedException("上传文件失败:" + e.getMessage());
|
||||||
@@ -150,6 +175,7 @@ public class AwsOssAdapter extends AStorageAdapter {
|
|||||||
object.setPath(getRelativePath(item.getKey().substring(0, item.getKey().lastIndexOf("/"))));
|
object.setPath(getRelativePath(item.getKey().substring(0, item.getKey().lastIndexOf("/"))));
|
||||||
object.setName(item.getKey().substring(item.getKey().lastIndexOf("/") + 1));
|
object.setName(item.getKey().substring(item.getKey().lastIndexOf("/") + 1));
|
||||||
object.setSize(item.getSize());
|
object.setSize(item.getSize());
|
||||||
|
object.setModifyTime(item.getLastModified());
|
||||||
object.setRawObject(item);
|
object.setRawObject(item);
|
||||||
return object;
|
return object;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
@@ -220,14 +246,57 @@ public class AwsOssAdapter extends AStorageAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private S3Wrapper getS3Client() {
|
private S3Wrapper getS3Client() {
|
||||||
BasicAWSCredentials basicAwsCred = new BasicAWSCredentials(config.getAccessKeyId(), config.getAccessKeySecret());
|
AwsOssStorageConfig currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s3Client == null) {
|
||||||
|
synchronized (clientLock) {
|
||||||
|
if (s3Client == null) {
|
||||||
|
// 在同步块内再次检查配置,确保配置一致性
|
||||||
|
currentConfig = this.config;
|
||||||
|
if (currentConfig == null) {
|
||||||
|
throw new StorageConfigException("存储适配器未配置");
|
||||||
|
}
|
||||||
|
BasicAWSCredentials basicAwsCred = new BasicAWSCredentials(
|
||||||
|
currentConfig.getAccessKeyId(),
|
||||||
|
currentConfig.getAccessKeySecret()
|
||||||
|
);
|
||||||
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
||||||
clientConfiguration.setProtocol(Protocol.HTTPS);
|
clientConfiguration.setProtocol(Protocol.HTTPS);
|
||||||
AmazonS3Client s3 = new AmazonS3Client(basicAwsCred,clientConfiguration);
|
s3Client = new AmazonS3Client(basicAwsCred, clientConfiguration);
|
||||||
S3ClientOptions options = S3ClientOptions.builder().setPathStyleAccess(true).setPayloadSigningEnabled(true).disableChunkedEncoding().build();
|
S3ClientOptions options = S3ClientOptions.builder()
|
||||||
s3.setS3ClientOptions(options);
|
.setPathStyleAccess(true)
|
||||||
s3.setEndpoint(config.getEndpoint());
|
.setPayloadSigningEnabled(true)
|
||||||
return new S3Wrapper(s3);
|
.disableChunkedEncoding()
|
||||||
|
.build();
|
||||||
|
s3Client.setS3ClientOptions(options);
|
||||||
|
s3Client.setEndpoint(currentConfig.getEndpoint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new S3Wrapper(s3Client, false); // false 表示不自动关闭共享客户端
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置客户端连接(配置更新时调用)
|
||||||
|
private void resetClient() {
|
||||||
|
synchronized (clientLock) {
|
||||||
|
if (s3Client != null) {
|
||||||
|
s3Client.shutdown();
|
||||||
|
s3Client = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动关闭客户端的方法,用于适配器销毁时
|
||||||
|
public void shutdown() {
|
||||||
|
synchronized (clientLock) {
|
||||||
|
if (s3Client != null) {
|
||||||
|
s3Client.shutdown();
|
||||||
|
s3Client = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildPath(String... paths) {
|
private String buildPath(String... paths) {
|
||||||
@@ -242,10 +311,18 @@ public class AwsOssAdapter extends AStorageAdapter {
|
|||||||
return StorageUtil.getRelativePath(path, config.getPrefix());
|
return StorageUtil.getRelativePath(path, config.getPrefix());
|
||||||
}
|
}
|
||||||
|
|
||||||
public record S3Wrapper(AmazonS3Client s3Client) implements AutoCloseable {
|
public record S3Wrapper(AmazonS3Client s3Client, boolean autoClose) implements AutoCloseable {
|
||||||
|
|
||||||
|
public S3Wrapper(AmazonS3Client s3Client) {
|
||||||
|
this(s3Client, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
// 只有非共享客户端才自动关闭
|
||||||
|
if (autoClose && s3Client != null) {
|
||||||
s3Client.shutdown();
|
s3Client.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -3,71 +3,207 @@ package com.ycwl.basic.storage.adapters;
|
|||||||
import com.ycwl.basic.storage.entity.StorageConfig;
|
import com.ycwl.basic.storage.entity.StorageConfig;
|
||||||
import com.ycwl.basic.storage.entity.StorageFileObject;
|
import com.ycwl.basic.storage.entity.StorageFileObject;
|
||||||
import com.ycwl.basic.storage.enums.StorageAcl;
|
import com.ycwl.basic.storage.enums.StorageAcl;
|
||||||
|
import com.ycwl.basic.storage.exceptions.StorageConfigException;
|
||||||
|
import com.ycwl.basic.storage.exceptions.StorageException;
|
||||||
|
import com.ycwl.basic.storage.exceptions.UploadFileFailedException;
|
||||||
|
import com.ycwl.basic.storage.utils.StorageUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collections;
|
import java.nio.file.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class LocalStorageAdapter extends AStorageAdapter {
|
||||||
|
private volatile String basePath;
|
||||||
|
private volatile String baseUrl;
|
||||||
|
private volatile String prefix = "";
|
||||||
|
private final Object configLock = new Object();
|
||||||
|
|
||||||
public class LocalStorageAdapter extends AStorageAdapter{
|
|
||||||
@Override
|
@Override
|
||||||
public String identity() {
|
public String identity() {
|
||||||
return "";
|
return "LOCAL_STORAGE";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadConfig(Map<String, String> config) {
|
public void loadConfig(Map<String, String> config) {
|
||||||
|
String newBasePath = config.get("basePath");
|
||||||
|
String newBaseUrl = config.get("baseUrl");
|
||||||
|
String newPrefix = StringUtils.isNotBlank(config.get("prefix")) ? config.get("prefix") : "";
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(newBasePath)) {
|
||||||
|
throw new StorageConfigException("本地存储配置错误:basePath 不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(newBaseUrl)) {
|
||||||
|
throw new StorageConfigException("本地存储配置错误:baseUrl 不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保基础目录存在
|
||||||
|
try {
|
||||||
|
Files.createDirectories(Paths.get(newBasePath));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new StorageConfigException("创建本地存储目录失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (configLock) {
|
||||||
|
this.basePath = newBasePath;
|
||||||
|
this.baseUrl = newBaseUrl;
|
||||||
|
this.prefix = newPrefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setConfig(StorageConfig config) {
|
public void setConfig(StorageConfig config) {
|
||||||
|
throw new StorageConfigException("LocalStorageAdapter 不支持 StorageConfig 类型配置");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String uploadFile(String contentType, InputStream inputStream, String... path) {
|
public String uploadFile(String contentType, InputStream inputStream, String... path) {
|
||||||
return "";
|
if (inputStream == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String fullPath = buildLocalPath(path);
|
||||||
|
try {
|
||||||
|
// 确保父目录存在
|
||||||
|
Path filePath = Paths.get(fullPath);
|
||||||
|
Files.createDirectories(filePath.getParent());
|
||||||
|
|
||||||
|
// 复制文件内容到本地
|
||||||
|
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
return getUrl(path);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UploadFileFailedException("本地文件保存失败:" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteFile(String... path) {
|
public boolean deleteFile(String... path) {
|
||||||
|
try {
|
||||||
|
String fullPath = buildLocalPath(path);
|
||||||
|
return Files.deleteIfExists(Paths.get(fullPath));
|
||||||
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(String... path) {
|
public String getUrl(String... path) {
|
||||||
return "";
|
String relativePath = buildRelativePath(path);
|
||||||
|
return baseUrl + "/" + relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrlForDownload(Date expireDate, String... path) {
|
public String getUrlForDownload(Date expireDate, String... path) {
|
||||||
return "";
|
// 本地存储不支持带过期时间的URL,直接返回普通URL
|
||||||
|
return getUrl(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrlForUpload(Date expireDate, String contentType, String... path) {
|
public String getUrlForUpload(Date expireDate, String contentType, String... path) {
|
||||||
return "";
|
// 本地存储不支持预签名上传URL
|
||||||
|
return getUrl(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<StorageFileObject> listDir(String... path) {
|
public List<StorageFileObject> listDir(String... path) {
|
||||||
return Collections.emptyList();
|
String fullPath = buildLocalPath(path);
|
||||||
|
Path dirPath = Paths.get(fullPath);
|
||||||
|
|
||||||
|
if (!Files.exists(dirPath) || !Files.isDirectory(dirPath)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<StorageFileObject> result = new ArrayList<>();
|
||||||
|
try (Stream<Path> paths = Files.list(dirPath)) {
|
||||||
|
paths.forEach(filePath -> {
|
||||||
|
try {
|
||||||
|
StorageFileObject obj = new StorageFileObject();
|
||||||
|
obj.setName(filePath.getFileName().toString());
|
||||||
|
obj.setPath(getRelativePath(filePath.getParent().toString()));
|
||||||
|
obj.setSize(Files.size(filePath));
|
||||||
|
obj.setModifyTime(new Date(Files.getLastModifiedTime(filePath).toMillis()));
|
||||||
|
obj.setRawObject(filePath.toFile());
|
||||||
|
result.add(obj);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// 忽略无法读取的文件
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new StorageException("列举本地文件失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteDir(String... path) {
|
public boolean deleteDir(String... path) {
|
||||||
|
String fullPath = buildLocalPath(path);
|
||||||
|
Path dirPath = Paths.get(fullPath);
|
||||||
|
|
||||||
|
if (!Files.exists(dirPath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 递归删除目录及其内容
|
||||||
|
try (Stream<Path> paths = Files.walk(dirPath)) {
|
||||||
|
paths.sorted((a, b) -> b.compareTo(a)) // 从深到浅排序,确保先删除文件再删除目录
|
||||||
|
.forEach(filePath -> {
|
||||||
|
try {
|
||||||
|
Files.deleteIfExists(filePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// 忽略删除失败的文件
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return !Files.exists(dirPath);
|
||||||
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setAcl(StorageAcl acl, String... path) {
|
public boolean setAcl(StorageAcl acl, String... path) {
|
||||||
return false;
|
// 本地存储不支持ACL设置
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExists(String... path) {
|
public boolean isExists(String... path) {
|
||||||
return false;
|
String fullPath = buildLocalPath(path);
|
||||||
|
return Files.exists(Paths.get(fullPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildLocalPath(String... paths) {
|
||||||
|
String relativePath = buildRelativePath(paths);
|
||||||
|
return Paths.get(basePath, relativePath).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildRelativePath(String... paths) {
|
||||||
|
if (StringUtils.isNotBlank(prefix)) {
|
||||||
|
return StorageUtil.joinPath(prefix, paths);
|
||||||
|
} else {
|
||||||
|
return StorageUtil.joinPath(paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRelativePath(String fullPath) {
|
||||||
|
String basePathNormalized = Paths.get(basePath).toString();
|
||||||
|
if (fullPath.startsWith(basePathNormalized)) {
|
||||||
|
String relative = fullPath.substring(basePathNormalized.length());
|
||||||
|
if (relative.startsWith(File.separator)) {
|
||||||
|
relative = relative.substring(1);
|
||||||
|
}
|
||||||
|
return StorageUtil.getRelativePath(relative, prefix);
|
||||||
|
}
|
||||||
|
return fullPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -131,7 +131,7 @@ public class DynamicTaskGenerator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return face.getScenicId().equals(faceSample.getScenicId());
|
return face.getScenicId().equals(faceSample.getScenicId());
|
||||||
}).collect(Collectors.toList());
|
}).toList();
|
||||||
if (faceIdList.isEmpty()) {
|
if (faceIdList.isEmpty()) {
|
||||||
log.info("本景区人脸样本ID不在人脸样本库中,忽略任务:{}", task);
|
log.info("本景区人脸样本ID不在人脸样本库中,忽略任务:{}", task);
|
||||||
return;
|
return;
|
||||||
|
70
src/main/java/com/ycwl/basic/task/N9eSyncTask.java
Normal file
70
src/main/java/com/ycwl/basic/task/N9eSyncTask.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package com.ycwl.basic.task;
|
||||||
|
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@EnableScheduling
|
||||||
|
public class N9eSyncTask {
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
@Scheduled(fixedRate = 1000 * 60L)
|
||||||
|
public void syncN9e() {
|
||||||
|
// 构建Basic认证头
|
||||||
|
String auth = "Basic " + Base64.encode("user001:ccc26da7b9aba533cbb263a36c07dcc4");
|
||||||
|
|
||||||
|
// 构建请求体
|
||||||
|
JSONObject requestBody = new JSONObject();
|
||||||
|
JSONArray queries = new JSONArray();
|
||||||
|
JSONObject query = new JSONObject();
|
||||||
|
query.put("key", "group_ids");
|
||||||
|
query.put("op", "==");
|
||||||
|
JSONArray values = new JSONArray();
|
||||||
|
values.add(4);
|
||||||
|
query.put("values", values);
|
||||||
|
queries.add(query);
|
||||||
|
requestBody.put("queries", queries);
|
||||||
|
|
||||||
|
// 发送POST请求
|
||||||
|
HttpResponse response = HttpUtil.createPost("https://n9e.jerryyan.top/v1/n9e/target/list")
|
||||||
|
.header("Authorization", auth)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(requestBody.toJSONString())
|
||||||
|
.execute();
|
||||||
|
JSONObject respData = JSON.parseObject(response.body());
|
||||||
|
if (StringUtils.isNotBlank(respData.getString("err"))) {
|
||||||
|
log.warn("N9E信息获取失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONObject data = respData.getJSONObject("dat");
|
||||||
|
if (data.getInteger("total") <= 0) {
|
||||||
|
log.warn("N9E信息为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONArray list = data.getJSONArray("list");
|
||||||
|
list.forEach(item -> {
|
||||||
|
JSONObject itemObj = (JSONObject) item;
|
||||||
|
String ident = itemObj.getString("ident");
|
||||||
|
Long updateAt = itemObj.getLong("update_at");
|
||||||
|
redisTemplate.opsForValue().set("ext_device:online:" + ident, updateAt.toString(), 1, TimeUnit.DAYS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -7,7 +7,9 @@ import com.ycwl.basic.constant.StorageConstant;
|
|||||||
import com.ycwl.basic.device.DeviceFactory;
|
import com.ycwl.basic.device.DeviceFactory;
|
||||||
import com.ycwl.basic.device.entity.common.FileObject;
|
import com.ycwl.basic.device.entity.common.FileObject;
|
||||||
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
|
import com.ycwl.basic.device.operator.IDeviceStorageOperator;
|
||||||
|
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
||||||
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
|
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
|
||||||
|
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
|
||||||
import com.ycwl.basic.repository.DeviceRepository;
|
import com.ycwl.basic.repository.DeviceRepository;
|
||||||
import com.ycwl.basic.mapper.FaceSampleMapper;
|
import com.ycwl.basic.mapper.FaceSampleMapper;
|
||||||
import com.ycwl.basic.mapper.SourceMapper;
|
import com.ycwl.basic.mapper.SourceMapper;
|
||||||
@@ -16,6 +18,8 @@ import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
|||||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||||
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
|
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
|
||||||
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
||||||
|
import com.ycwl.basic.repository.FaceRepository;
|
||||||
|
import com.ycwl.basic.repository.ScenicRepository;
|
||||||
import com.ycwl.basic.repository.TemplateRepository;
|
import com.ycwl.basic.repository.TemplateRepository;
|
||||||
import com.ycwl.basic.storage.StorageFactory;
|
import com.ycwl.basic.storage.StorageFactory;
|
||||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||||
@@ -57,6 +61,8 @@ public class VideoPieceGetter {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private FaceSampleMapper faceSampleMapper;
|
private FaceSampleMapper faceSampleMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private FaceRepository faceRepository;
|
||||||
|
@Autowired
|
||||||
private DeviceRepository deviceRepository;
|
private DeviceRepository deviceRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SourceMapper sourceMapper;
|
private SourceMapper sourceMapper;
|
||||||
@@ -68,6 +74,8 @@ public class VideoPieceGetter {
|
|||||||
private TaskStatusBiz taskStatusBiz;
|
private TaskStatusBiz taskStatusBiz;
|
||||||
@Autowired
|
@Autowired
|
||||||
private VideoReUploader videoReUploader;
|
private VideoReUploader videoReUploader;
|
||||||
|
@Autowired
|
||||||
|
private ScenicRepository scenicRepository;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class Task {
|
public static class Task {
|
||||||
@@ -208,7 +216,7 @@ public class VideoPieceGetter {
|
|||||||
log.info("executor已结束![A:{}/T:{}/F:{}]", executor.getActiveCount(), executor.getTaskCount(), executor.getCompletedTaskCount());
|
log.info("executor已结束![A:{}/T:{}/F:{}]", executor.getActiveCount(), executor.getTaskCount(), executor.getCompletedTaskCount());
|
||||||
executor.close();
|
executor.close();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
return;
|
log.info("executor已中断![A:{}/T:{}/F:{}]", executor.getActiveCount(), executor.getTaskCount(), executor.getCompletedTaskCount());
|
||||||
} finally {
|
} finally {
|
||||||
if (task.faceId != null) {
|
if (task.faceId != null) {
|
||||||
taskStatusBiz.setFaceCutStatus(task.faceId, 1);
|
taskStatusBiz.setFaceCutStatus(task.faceId, 1);
|
||||||
@@ -220,6 +228,29 @@ public class VideoPieceGetter {
|
|||||||
task.getCallback().onInvoke();
|
task.getCallback().onInvoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (task.getFaceId() != null) {
|
||||||
|
FaceEntity face = faceRepository.getFace(task.getFaceId());
|
||||||
|
if (face != null) {
|
||||||
|
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(face.getScenicId());
|
||||||
|
if (scenicConfig != null) {
|
||||||
|
// 免费送
|
||||||
|
List<MemberSourceEntity> sourceEntities = sourceMapper.listByFaceRelation(face.getScenicId(), face.getId(), 1);
|
||||||
|
if (sourceEntities.stream().noneMatch(item -> Integer.valueOf(1).equals(item.getIsFree()))) {
|
||||||
|
List<Long> freeSourceRelationIds = new ArrayList<>();
|
||||||
|
if (scenicConfig.getVideoFreeNum() != null && scenicConfig.getVideoFreeNum() > 0) {
|
||||||
|
if (scenicConfig.getVideoFreeNum() > sourceEntities.size()) {
|
||||||
|
freeSourceRelationIds.addAll(sourceEntities.stream().map(MemberSourceEntity::getId).toList());
|
||||||
|
} else {
|
||||||
|
freeSourceRelationIds.addAll(sourceEntities.stream().limit(scenicConfig.getVideoFreeNum()).map(MemberSourceEntity::getId).toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!freeSourceRelationIds.isEmpty()) {
|
||||||
|
sourceMapper.freeRelations(freeSourceRelationIds, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doCut(Long deviceId, Long faceSampleId, Date baseTime, Task task) {
|
private boolean doCut(Long deviceId, Long faceSampleId, Date baseTime, Task task) {
|
||||||
|
@@ -1,14 +1,19 @@
|
|||||||
package com.ycwl.basic.utils;
|
package com.ycwl.basic.utils;
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base64;
|
import cn.hutool.core.codec.Base64;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class ImageUtils {
|
public class ImageUtils {
|
||||||
public static MultipartFile base64ToMultipartFile(String base64) {
|
public static MultipartFile base64ToMultipartFile(String base64) {
|
||||||
String[] baseStrs = base64.split(",");
|
String[] baseStrs = base64.split(",");
|
||||||
@@ -21,6 +26,37 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
return new Base64DecodedMultipartFile(b, baseStrs[0]);
|
return new Base64DecodedMultipartFile(b, baseStrs[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MultipartFile cropImage(MultipartFile file, int x, int y, int w, int h) throws IOException {
|
||||||
|
BufferedImage image = ImageIO.read(file.getInputStream());
|
||||||
|
log.info("图片宽高:{}", image.getWidth() + "x" + image.getHeight());
|
||||||
|
log.info("图片裁切:{}@{}", w + "x" + h, x + "," + y);
|
||||||
|
if (image.getWidth() < w) {
|
||||||
|
w = image.getWidth();
|
||||||
|
}
|
||||||
|
if (image.getHeight() < h) {
|
||||||
|
h = image.getHeight();
|
||||||
|
}
|
||||||
|
int targetX = x;
|
||||||
|
if (x < 0) {
|
||||||
|
targetX = 0;
|
||||||
|
} else if ((x + w) > image.getWidth()) {
|
||||||
|
targetX = image.getWidth() - w;
|
||||||
|
}
|
||||||
|
int targetY = y;
|
||||||
|
if (y < 0) {
|
||||||
|
targetY = 0;
|
||||||
|
} else if ((y + h) > image.getHeight()) {
|
||||||
|
targetY = image.getHeight() - h;
|
||||||
|
}
|
||||||
|
log.info("图片实际裁切:{}@{}", w + "x" + h, targetX + "," + targetY);
|
||||||
|
BufferedImage targetImage = image.getSubimage(targetX, targetY, w, h);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ImageIO.write(targetImage, "jpg", baos);
|
||||||
|
baos.close();
|
||||||
|
return new Base64DecodedMultipartFile(baos.toByteArray(), "image/jpeg");
|
||||||
|
}
|
||||||
|
|
||||||
public static class Base64DecodedMultipartFile implements MultipartFile {
|
public static class Base64DecodedMultipartFile implements MultipartFile {
|
||||||
|
|
||||||
private final byte[] imgContent;
|
private final byte[] imgContent;
|
||||||
|
@@ -13,6 +13,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
|||||||
import jakarta.servlet.http.Cookie;
|
import jakarta.servlet.http.Cookie;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -49,10 +51,19 @@ public class JwtTokenUtil {
|
|||||||
|
|
||||||
public static String generateToken(JwtInfo jwtInfo, int expire) throws Exception {
|
public static String generateToken(JwtInfo jwtInfo, int expire) throws Exception {
|
||||||
LocalDateTime expireTime = LocalDateTime.now().plusDays(expire);
|
LocalDateTime expireTime = LocalDateTime.now().plusDays(expire);
|
||||||
|
if (jwtInfo.getExpireTime() != null) {
|
||||||
|
expireTime = jwtInfo.getExpireTime();
|
||||||
|
}
|
||||||
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
|
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
|
||||||
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
|
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
public static String generateToken(JwtInfo jwtInfo, Date expireTime) throws Exception {
|
||||||
|
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
|
||||||
|
LocalDateTime dt = expireTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, dt);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -3,6 +3,7 @@ package com.ycwl.basic.utils;
|
|||||||
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpResponse;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -12,8 +13,10 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
|
|
||||||
public class WxMpUtil {
|
public class WxMpUtil {
|
||||||
private static final String GET_WXA_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s";
|
private static final String GET_WXA_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s";
|
||||||
|
private static final String GET_WXA_CODE_UNLIMITED_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
|
||||||
private static final String GET_URL_LICK_URL = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=%s";
|
private static final String GET_URL_LICK_URL = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=%s";
|
||||||
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||||
|
private static final String STABLE_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/stable_token?grant_type=client_credential&appid=%s&secret=%s&force_refresh=false";
|
||||||
public static final String GET_USER_PHONE_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";
|
public static final String GET_USER_PHONE_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";
|
||||||
private static final Map<String, String> tokens = new ConcurrentHashMap<>();
|
private static final Map<String, String> tokens = new ConcurrentHashMap<>();
|
||||||
private static final Map<String, Date> expireTimes = new ConcurrentHashMap<>();
|
private static final Map<String, Date> expireTimes = new ConcurrentHashMap<>();
|
||||||
@@ -31,12 +34,27 @@ public class WxMpUtil {
|
|||||||
tokens.remove(appId);
|
tokens.remove(appId);
|
||||||
}
|
}
|
||||||
return tokens.computeIfAbsent(appId, (k) -> {
|
return tokens.computeIfAbsent(appId, (k) -> {
|
||||||
|
String token;
|
||||||
|
if (!System.getProperty("os.name").toLowerCase().startsWith("win")) {
|
||||||
|
String url = String.format(STABLE_ACCESS_TOKEN_URL, appId, appSecret);
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("grant_type", "client_credential");
|
||||||
|
params.put("appid", appId);
|
||||||
|
params.put("secret", appSecret);
|
||||||
|
params.put("force_refresh", false);
|
||||||
|
String response = HttpUtil.post(url, params.toJSONString());
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(response);
|
||||||
|
token = jsonObject.getString("access_token");
|
||||||
|
Date expireTime = new Date(System.currentTimeMillis() + jsonObject.getInteger("expires_in") * 1000 / 2);
|
||||||
|
expireTimes.put(appId, expireTime);
|
||||||
|
} else {
|
||||||
String url = String.format(ACCESS_TOKEN_URL, appId, appSecret);
|
String url = String.format(ACCESS_TOKEN_URL, appId, appSecret);
|
||||||
String response = HttpUtil.get(url);
|
String response = HttpUtil.get(url);
|
||||||
JSONObject jsonObject = JSONObject.parseObject(response);
|
JSONObject jsonObject = JSONObject.parseObject(response);
|
||||||
String token = jsonObject.getString("access_token");
|
token = jsonObject.getString("access_token");
|
||||||
Date expireTime = new Date(System.currentTimeMillis() + jsonObject.getInteger("expires_in") * 1000 / 2);
|
Date expireTime = new Date(System.currentTimeMillis() + jsonObject.getInteger("expires_in") * 1000 / 2);
|
||||||
expireTimes.put(appId, expireTime);
|
expireTimes.put(appId, expireTime);
|
||||||
|
}
|
||||||
return token;
|
return token;
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
@@ -66,6 +84,28 @@ public class WxMpUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void generateUnlimitedWXAQRCode(String appId, String appSecret, String path, String scene, File targetFile) throws Exception {
|
||||||
|
String url = String.format(GET_WXA_CODE_UNLIMITED_URL, getAccessToken(appId, appSecret));
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("page", path);
|
||||||
|
json.put("scene", scene);
|
||||||
|
json.put("check_path", false);
|
||||||
|
|
||||||
|
try (HttpResponse response = HttpUtil.createPost(url).body(json.toJSONString()).header("Content-Type", "application/json").execute()) {
|
||||||
|
if (response.getStatus() != 200) {
|
||||||
|
throw new Exception("获取小程序二维码失败,原因为:" + response.body());
|
||||||
|
}
|
||||||
|
InputStream inputStream = response.bodyStream();
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(targetFile)) {
|
||||||
|
int len;
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
while ((len = inputStream.read(buffer)) != -1) {
|
||||||
|
fos.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String generateUrlLink(String appId, String appSecret, String path, String query) throws Exception {
|
public static String generateUrlLink(String appId, String appSecret, String path, String query) throws Exception {
|
||||||
String url = String.format(GET_URL_LICK_URL, getAccessToken(appId, appSecret));
|
String url = String.format(GET_URL_LICK_URL, getAccessToken(appId, appSecret));
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
<update id="update" parameterType="com.ycwl.basic.model.pc.adminUser.req.AddOrUpdateAdminUserReqVO">
|
<update id="update" parameterType="com.ycwl.basic.model.pc.adminUser.req.AddOrUpdateAdminUserReqVO">
|
||||||
update admin_user
|
update admin_user
|
||||||
set `role_id` =#{roleId}, `account`=#{account}, `name`=#{name}, `phone`=#{phone}
|
set `role_id` =#{roleId}, `account`=#{account}, `name`=#{name}, `phone`=#{phone}
|
||||||
|
<if test="password != null">, `password`=#{password}</if>, update_at = NOW()
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
<update id="updatePassword">
|
<update id="updatePassword">
|
||||||
@@ -77,7 +78,8 @@
|
|||||||
au.name as staffName,
|
au.name as staffName,
|
||||||
au.id as staffId,
|
au.id as staffId,
|
||||||
au.password,
|
au.password,
|
||||||
au.role_id
|
au.role_id,
|
||||||
|
au.update_at
|
||||||
from admin_user au
|
from admin_user au
|
||||||
where account = #{account}
|
where account = #{account}
|
||||||
and au.status = 1
|
and au.status = 1
|
||||||
@@ -89,4 +91,16 @@
|
|||||||
where id = #{id}
|
where id = #{id}
|
||||||
and status = 1
|
and status = 1
|
||||||
</select>
|
</select>
|
||||||
|
<select id="getById" resultType="com.ycwl.basic.model.pc.adminUser.entity.LoginEntity">
|
||||||
|
select
|
||||||
|
au.account,
|
||||||
|
au.name as staffName,
|
||||||
|
au.id as staffId,
|
||||||
|
au.password,
|
||||||
|
au.role_id,
|
||||||
|
au.update_at
|
||||||
|
from admin_user au
|
||||||
|
where id = #{id}
|
||||||
|
and au.status = 1
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
17
src/main/resources/mapper/AioDeviceMapper.xml
Normal file
17
src/main/resources/mapper/AioDeviceMapper.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="com.ycwl.basic.mapper.AioDeviceMapper">
|
||||||
|
<select id="getById" resultType="com.ycwl.basic.model.aio.entity.AioDeviceEntity">
|
||||||
|
select * from aio_device where id = #{id} limit 1
|
||||||
|
</select>
|
||||||
|
<select id="getByKey" resultType="com.ycwl.basic.model.aio.entity.AioDeviceEntity">
|
||||||
|
select * from aio_device where access_key = #{accessKey} limit 1
|
||||||
|
</select>
|
||||||
|
<select id="getBannerByDeviceId" resultType="com.ycwl.basic.model.aio.entity.AioDeviceBannerEntity">
|
||||||
|
select * from aio_device_banner where device_id = #{deviceId}
|
||||||
|
</select>
|
||||||
|
<select id="getPriceConfigByDeviceId"
|
||||||
|
resultType="com.ycwl.basic.model.aio.entity.AioDevicePriceConfigEntity">
|
||||||
|
select * from aio_device_price_config where id = #{deviceId}
|
||||||
|
</select>
|
||||||
|
</mapper>
|
@@ -109,6 +109,7 @@
|
|||||||
from device d
|
from device d
|
||||||
left join device_preview_config p on d.id = p.device_id and p.status = 1
|
left join device_preview_config p on d.id = p.device_id and p.status = 1
|
||||||
where d.scenic_id = #{scenicId}
|
where d.scenic_id = #{scenicId}
|
||||||
|
order by d.sort
|
||||||
</select>
|
</select>
|
||||||
<select id="deviceCountByScenicId" resultType="com.ycwl.basic.model.mobile.scenic.ScenicDeviceCountVO">
|
<select id="deviceCountByScenicId" resultType="com.ycwl.basic.model.mobile.scenic.ScenicDeviceCountVO">
|
||||||
select count(1) totalDeviceCount
|
select count(1) totalDeviceCount
|
||||||
|
11
src/main/resources/mapper/ExtraDeviceMapper.xml
Normal file
11
src/main/resources/mapper/ExtraDeviceMapper.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="com.ycwl.basic.mapper.ExtraDeviceMapper">
|
||||||
|
<select id="listExtraDeviceByScenicId" resultType="com.ycwl.basic.model.pc.device.resp.DeviceRespVO">
|
||||||
|
select d.id, d.ident as no, d.scenic_id, d.name, d.status, s.name as scenic_name
|
||||||
|
from extra_device d
|
||||||
|
left join scenic s on d.scenic_id = s.id
|
||||||
|
where d.scenic_id = #{scenicId}
|
||||||
|
and d.status = 1
|
||||||
|
</select>
|
||||||
|
</mapper>
|
@@ -2,75 +2,18 @@
|
|||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.ycwl.basic.mapper.MenuMapper">
|
<mapper namespace="com.ycwl.basic.mapper.MenuMapper">
|
||||||
<insert id="addRoleMenu">
|
<insert id="addRoleMenu">
|
||||||
insert into role_menu(`role_id`, `menu_id`)
|
replace role_menu(`role_id`, `menu_str`, `perm_str`, `update_time`)
|
||||||
values
|
values (#{id}, #{menuStr}, #{permStr}, NOW())
|
||||||
<foreach collection="list" item="item" separator=",">
|
|
||||||
(#{id},#{item})
|
|
||||||
</foreach>
|
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="add">
|
|
||||||
insert into menu(id, parent_id, target, `name`, type, sort, permission_url, is_remove, business_type, icon)
|
|
||||||
values
|
|
||||||
(#{id}, #{parentId}, #{target}, #{name}, #{type}, #{sort}, #{permissionUrl}, #{isRemove}, #{businessType}, #{icon})
|
|
||||||
</insert>
|
|
||||||
<update id="update">
|
|
||||||
update menu
|
|
||||||
<set>
|
|
||||||
<if test="parentId!= null ">
|
|
||||||
parent_id = #{parentId},
|
|
||||||
</if>
|
|
||||||
<if test="target!= null and target!= ''">
|
|
||||||
target = #{target},
|
|
||||||
</if>
|
|
||||||
<if test="name!= null and name!= ''">
|
|
||||||
`name` = #{name},
|
|
||||||
</if>
|
|
||||||
<if test="type!= null ">
|
|
||||||
`type` = #{type},
|
|
||||||
</if>
|
|
||||||
<if test="sort!= null ">
|
|
||||||
sort = #{sort},
|
|
||||||
</if>
|
|
||||||
<if test="permissionUrl!= null and permissionUrl!= ''">
|
|
||||||
permission_url = #{permissionUrl},
|
|
||||||
</if>
|
|
||||||
<if test="businessType!= null ">
|
|
||||||
business_type = #{businessType},
|
|
||||||
</if>
|
|
||||||
<if test="icon!= null and icon!= ''">
|
|
||||||
icon = #{icon},
|
|
||||||
</if>
|
|
||||||
</set>
|
|
||||||
where id = #{id}
|
|
||||||
</update>
|
|
||||||
|
|
||||||
<delete id="deleteRoleMenuByRoleId">
|
<delete id="deleteRoleMenuByRoleId">
|
||||||
delete
|
delete
|
||||||
from role_menu
|
from role_menu
|
||||||
where role_id = #{id}
|
where role_id = #{id}
|
||||||
</delete>
|
</delete>
|
||||||
<delete id="deleteById">
|
<select id="getPermissionByRoleId" resultType="com.ycwl.basic.model.pc.role.resp.RolePermissionResp">
|
||||||
update menu set is_remove=1 where id = #{id}
|
select role_id, menu_str, perm_str
|
||||||
</delete>
|
|
||||||
<delete id="deleteRoleMenuByMenuId">
|
|
||||||
delete
|
|
||||||
from role_menu
|
from role_menu
|
||||||
where menu_id = #{id}
|
where role_id = #{id}
|
||||||
</delete>
|
|
||||||
|
|
||||||
<select id="getListByType" resultType="com.ycwl.basic.model.pc.menu.MenuNode">
|
|
||||||
select id,
|
|
||||||
parent_id,
|
|
||||||
target,
|
|
||||||
`name`,
|
|
||||||
`type`,
|
|
||||||
sort
|
|
||||||
from menu
|
|
||||||
where is_remove = 0
|
|
||||||
<if test="type!= null ">
|
|
||||||
and business_type = #{type}
|
|
||||||
</if>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
@@ -121,6 +121,7 @@
|
|||||||
WHEN '1' THEN '录像集'
|
WHEN '1' THEN '录像集'
|
||||||
WHEN '2' THEN '照片集'
|
WHEN '2' THEN '照片集'
|
||||||
WHEN '3' THEN '照片打印'
|
WHEN '3' THEN '照片打印'
|
||||||
|
WHEN '4' THEN '一体机照片打印'
|
||||||
ELSE '其他'
|
ELSE '其他'
|
||||||
END AS goods_name,
|
END AS goods_name,
|
||||||
CASE oi.goods_type
|
CASE oi.goods_type
|
||||||
@@ -141,6 +142,7 @@
|
|||||||
WHEN '1' THEN msd.url
|
WHEN '1' THEN msd.url
|
||||||
WHEN '2' THEN msd.url
|
WHEN '2' THEN msd.url
|
||||||
WHEN '3' THEN mpd.url
|
WHEN '3' THEN mpd.url
|
||||||
|
WHEN '4' THEN msd.url
|
||||||
END AS imgUrl
|
END AS imgUrl
|
||||||
FROM order_item oi
|
FROM order_item oi
|
||||||
LEFT JOIN `order` o ON oi.order_id = o.id
|
LEFT JOIN `order` o ON oi.order_id = o.id
|
||||||
|
@@ -65,6 +65,19 @@
|
|||||||
END)
|
END)
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
<update id="updateHost">
|
||||||
|
update render_worker
|
||||||
|
set platform = #{status.platform},
|
||||||
|
runtime_version = #{status.runtimeVersion},
|
||||||
|
version = #{status.version},
|
||||||
|
cpu_count = #{status.cpuCount},
|
||||||
|
cpu_usage = #{status.cpuUsage},
|
||||||
|
memory_total = #{status.memoryTotal},
|
||||||
|
memory_available = #{status.memoryAvailable},
|
||||||
|
support_feature = #{status.supportFeature},
|
||||||
|
update_at = #{status.updateAt}
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
<delete id="deleteById">
|
<delete id="deleteById">
|
||||||
delete from render_worker where id = #{id}
|
delete from render_worker where id = #{id}
|
||||||
</delete>
|
</delete>
|
||||||
|
@@ -9,14 +9,16 @@
|
|||||||
<update id="delete">
|
<update id="delete">
|
||||||
update
|
update
|
||||||
role
|
role
|
||||||
set is_remove=1
|
set is_remove=1,
|
||||||
|
`update_time`=NOW()
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="update" parameterType="com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO">
|
<update id="update" parameterType="com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO">
|
||||||
update
|
update
|
||||||
role
|
role
|
||||||
set `name`=#{name}
|
set `name`=#{name},
|
||||||
|
`update_time`=NOW()
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
@@ -59,7 +59,7 @@
|
|||||||
select s.scenic_id, s.device_id
|
select s.scenic_id, s.device_id
|
||||||
from member_source ms
|
from member_source ms
|
||||||
left join source s on ms.source_id = s.id
|
left join source s on ms.source_id = s.id
|
||||||
where ms.type = 1
|
where ms.type = 2
|
||||||
and s.create_time >= #{start}
|
and s.create_time >= #{start}
|
||||||
and s.create_time <= #{end}
|
and s.create_time <= #{end}
|
||||||
group by s.scenic_id, s.device_id, ms.face_id
|
group by s.scenic_id, s.device_id, ms.face_id
|
||||||
|
@@ -126,7 +126,9 @@
|
|||||||
pay_config_json=#{payConfigJson},
|
pay_config_json=#{payConfigJson},
|
||||||
image_source_pack_hint=#{imageSourcePackHint},
|
image_source_pack_hint=#{imageSourcePackHint},
|
||||||
video_source_pack_hint=#{videoSourcePackHint},
|
video_source_pack_hint=#{videoSourcePackHint},
|
||||||
extra_notification_time=#{extraNotificationTime}
|
extra_notification_time=#{extraNotificationTime},
|
||||||
|
photo_free_num= #{photoFreeNum},
|
||||||
|
video_free_num= #{videoFreeNum}
|
||||||
</set>
|
</set>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
@@ -6,11 +6,11 @@
|
|||||||
values (#{id}, #{scenicId}, #{deviceId}, #{url}, #{videoUrl}, #{type}, #{faceSampleId}, #{posJson}, #{createTime})
|
values (#{id}, #{scenicId}, #{deviceId}, #{url}, #{videoUrl}, #{type}, #{faceSampleId}, #{posJson}, #{createTime})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="addRelation">
|
<insert id="addRelation">
|
||||||
replace member_source(scenic_id, face_id, member_id, source_id, is_buy, type, order_id, is_free)
|
replace member_source(scenic_id, face_id, member_id, source_id, is_buy, type, order_id<if test="isFree">, is_free</if>)
|
||||||
values (#{scenicId}, #{faceId}, #{memberId}, #{sourceId}, #{isBuy}, #{type}, #{orderId}, #{isFree})
|
values (#{scenicId}, #{faceId}, #{memberId}, #{sourceId}, #{isBuy}, #{type}, #{orderId}<if test="isFree">, #{isFree}</if>)
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="addRelations">
|
<insert id="addRelations">
|
||||||
replace member_source(scenic_id, face_id, member_id, source_id, is_buy, type, order_id, is_free)
|
insert IGNORE member_source(scenic_id, face_id, member_id, source_id, is_buy, type, order_id, is_free)
|
||||||
values
|
values
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.scenicId}, #{item.faceId}, #{item.memberId}, #{item.sourceId}, #{item.isBuy}, #{item.type}, #{item.orderId}, #{item.isFree})
|
(#{item.scenicId}, #{item.faceId}, #{item.memberId}, #{item.sourceId}, #{item.isBuy}, #{item.type}, #{item.orderId}, #{item.isFree})
|
||||||
@@ -42,6 +42,14 @@
|
|||||||
</set>
|
</set>
|
||||||
where member_id = #{memberId} and face_id = #{faceId} and `type` = #{type}
|
where member_id = #{memberId} and face_id = #{faceId} and `type` = #{type}
|
||||||
</update>
|
</update>
|
||||||
|
<update id="freeRelations">
|
||||||
|
update member_source
|
||||||
|
set is_free = 1
|
||||||
|
where type = #{type} and id in
|
||||||
|
<foreach item="item" collection="ids" open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</update>
|
||||||
<delete id="deleteById">
|
<delete id="deleteById">
|
||||||
delete from source where id = #{id}
|
delete from source where id = #{id}
|
||||||
</delete>
|
</delete>
|
||||||
@@ -227,4 +235,11 @@
|
|||||||
<if test="type!=null">and ms.type = #{type} </if>
|
<if test="type!=null">and ms.type = #{type} </if>
|
||||||
<if test="faceId!=null">and ms.face_id = #{faceId} </if>
|
<if test="faceId!=null">and ms.face_id = #{faceId} </if>
|
||||||
</select>
|
</select>
|
||||||
|
<select id="listByFaceRelation" resultType="com.ycwl.basic.model.pc.source.entity.MemberSourceEntity">
|
||||||
|
select *
|
||||||
|
from member_source ms
|
||||||
|
where ms.member_id = #{memberId}
|
||||||
|
and ms.face_id = #{faceId}
|
||||||
|
<if test="type!=null">and ms.type = #{type} </if>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
@@ -12,10 +12,10 @@
|
|||||||
where
|
where
|
||||||
(status = 1 or status = 2) and scenic_id = #{scenicId}
|
(status = 1 or status = 2) and scenic_id = #{scenicId}
|
||||||
<if test="startTime!= null">
|
<if test="startTime!= null">
|
||||||
and create_at >= #{startTime}
|
and pay_at >= #{startTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime!= null">
|
<if test="endTime!= null">
|
||||||
and create_at <= #{endTime}
|
and pay_at <= #{endTime}
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
<select id="countPreviewVideoOfMember" resultType="java.lang.Integer">
|
<select id="countPreviewVideoOfMember" resultType="java.lang.Integer">
|
||||||
@@ -61,17 +61,20 @@
|
|||||||
SELECT
|
SELECT
|
||||||
IFNULL(count(1), 0) AS count
|
IFNULL(count(1), 0) AS count
|
||||||
FROM (
|
FROM (
|
||||||
select count(1) as count
|
select 1
|
||||||
from `order`
|
FROM `t_stats_record` r
|
||||||
where scenic_id = #{scenicId}
|
left join `t_stats` s on r.trace_id=s.trace_id
|
||||||
|
where r.trace_id in (select trace_id from `t_stats_record` where action = 'ENTER_SCENIC' and `identifier`=#{scenicId})
|
||||||
|
and action = 'CLICK'
|
||||||
|
and identifier = 'BUY'
|
||||||
<if test="startTime!= null">
|
<if test="startTime!= null">
|
||||||
and create_at >= #{startTime}
|
and s.create_time >= #{startTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime!= null">
|
<if test="endTime!= null">
|
||||||
and create_at <= #{endTime}
|
and s.create_time <= #{endTime}
|
||||||
</if>
|
</if>
|
||||||
group by member_id
|
group by s.member_id
|
||||||
)a
|
) AS subquery;
|
||||||
</select>
|
</select>
|
||||||
<select id="countPayOfMember" resultType="java.lang.Integer">
|
<select id="countPayOfMember" resultType="java.lang.Integer">
|
||||||
SELECT
|
SELECT
|
||||||
|
@@ -112,7 +112,7 @@
|
|||||||
</select>
|
</select>
|
||||||
<select id="listFor" resultType="com.ycwl.basic.model.mobile.scenic.content.ContentPageVO">
|
<select id="listFor" resultType="com.ycwl.basic.model.mobile.scenic.content.ContentPageVO">
|
||||||
select t.id templateId, t.scenic_id, s.name as scenic_name, t.`name`, pid, t.cover_url templateCoverUrl,
|
select t.id templateId, t.scenic_id, s.name as scenic_name, t.`name`, pid, t.cover_url templateCoverUrl,
|
||||||
0 as sourceType,
|
0 as sourceType, sort,
|
||||||
t.create_time, t.price
|
t.create_time, t.price
|
||||||
from template t left join scenic s on s.id = t.scenic_id
|
from template t left join scenic s on s.id = t.scenic_id
|
||||||
where t.scenic_id = #{scenicId} and pid = 0 and t.status = 1
|
where t.scenic_id = #{scenicId} and pid = 0 and t.status = 1
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 1.3 MiB |
@@ -16,7 +16,7 @@ public class WatermarkOperatorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testProcess() throws Exception {
|
public void testProcess() throws Exception {
|
||||||
WatermarkInfo info = new WatermarkInfo();
|
WatermarkInfo info = new WatermarkInfo();
|
||||||
info.setOriginalFile(new File("e2d32de7-6e85-4e07-b42f-477347073539.jpg"));
|
info.setOriginalFile(new File("38e1285c-84d0-464a-810d-053e9502e257.jpg"));
|
||||||
info.setQrcodeFile(new File("cxzh_t.jpg"));
|
info.setQrcodeFile(new File("cxzh_t.jpg"));
|
||||||
info.setScenicLine("川西竹海一日游!");
|
info.setScenicLine("川西竹海一日游!");
|
||||||
info.setDatetimeLine("2XXX年XX月XX日 留念");
|
info.setDatetimeLine("2XXX年XX月XX日 留念");
|
||||||
|
Reference in New Issue
Block a user