Compare commits

..

1 Commits

Author SHA1 Message Date
8a17392ae5 Jenkinsfile
Some checks are pending
Gitea/FrameTour-BE/pipeline/head Build queued...
2025-06-30 17:51:34 +08:00
83 changed files with 468 additions and 1844 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,3 @@
.idea/ .idea/
logs/ logs/
target/ target/
.claude

123
CLAUDE.md
View File

@@ -1,123 +0,0 @@
# 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. 遵循现有的错误处理和日志记录模式

12
Jenkinsfile vendored
View File

@@ -1,20 +1,20 @@
pipeline { pipeline {
agent any agent any
tools { environment {
jdk 'openjdk21' JAVA_HOME = "/opt/openjdk21.0.7"
maven 'Default' MAVEN_HOME = "/opt/apache-maven-3.9.9"
PATH = "${env.JAVA_HOME}/bin:${env.MAVEN_HOME}/bin:${env.PATH}"
} }
stages { stages {
stage('Build') { stage('Build') {
steps { steps {
sh 'mvn clean package -DskipTests=true' bat 'mvn clean package -DskipTests=true'
} }
} }
} }
post { post {
always { always {
archiveArtifacts artifacts: 'target/*.jar', allowEmptyArchive: true, onlyIfSuccessful: true archiveArtifacts artifacts: 'target/*.jar', allowEmptyArchive: false
publishGiteaAssets assets: 'target/*.jar', followSymlinks: false, onlyIfSuccessful: true
} }
} }
} }

View File

@@ -1,148 +0,0 @@
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));
}
}

View File

@@ -14,10 +14,8 @@ 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;
@@ -64,8 +62,6 @@ 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
@@ -202,7 +198,6 @@ 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;
@@ -213,11 +208,6 @@ 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"));
@@ -234,7 +224,6 @@ 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());
@@ -244,8 +233,6 @@ 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);

View File

@@ -78,13 +78,4 @@ 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");
}
} }

View File

@@ -2,7 +2,6 @@ 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;
@@ -50,20 +49,8 @@ public class AppScenicAccountController {
@ApiOperation("登录") @ApiOperation("登录")
@PostMapping("/login") @PostMapping("/login")
@IgnoreToken @IgnoreToken
public ApiResponse<ScenicLoginOldRespVO> login(@RequestBody ScenicLoginReq scenicLoginReq) throws Exception { public ApiResponse<ScenicLoginRespVO> login(@RequestBody ScenicLoginReq scenicLoginReq) throws Exception {
ApiResponse<ScenicLoginRespVO> logined = scenicService.login(scenicLoginReq); return 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")

View File

@@ -0,0 +1,45 @@
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);
}
}

View File

@@ -1,14 +1,10 @@
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;
@@ -32,29 +28,15 @@ 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(), ","))));
} 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(), ","))));
} }
return ApiResponse.success(new PermissionResp(Arrays.asList(StringUtils.split(permission.getPermString(), ",")), Arrays.asList(StringUtils.split(permission.getMenuString(), ","))));
} }
@ApiOperation("根据用户ID查询权限信息") @ApiOperation("根据用户ID查询权限信息")

View File

@@ -2,20 +2,16 @@ 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
@@ -28,38 +24,34 @@ 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);
} }
@@ -68,6 +60,7 @@ 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);
} }

View File

@@ -12,7 +12,6 @@ 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;
@@ -54,8 +53,6 @@ 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;
@@ -69,6 +66,7 @@ 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;
@@ -246,14 +244,8 @@ 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.getViidType() != null) { if (deviceConfig != null && deviceConfig.getViidType() != null) {
viidMode = deviceConfig.getViidType(); viidMode = deviceConfig.getViidType();
} }
Date shotTime = null; Date shotTime = null;
@@ -293,15 +285,13 @@ public class ViidController {
if (viidMode == 0) { if (viidMode == 0) {
// 遍历每个图片对象 // 遍历每个图片对象
// 先找到type14的图片 // 先找到type14的图片
List<SubImageInfoObject> type14ImageList = subImageList.getSubImageInfoObject().stream().filter(subImage -> "14".equals(subImage.getType())).toList(); List<SubImageInfoObject> type14ImageList = subImageList.getSubImageInfoObject().stream().filter(subImage -> "14".equals(subImage.getType())).collect(Collectors.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; String ext = subImage.getFileFormat();
if (subImage.getFileFormat().equalsIgnoreCase("jpeg")) { if (ext.equalsIgnoreCase("jpeg")) {
ext = "jpg"; ext = "jpg";
} else {
ext = subImage.getFileFormat();
} }
IStorageAdapter adapter = StorageFactory.use("faces"); IStorageAdapter adapter = StorageFactory.use("faces");
// Type=11 人脸 // Type=11 人脸
@@ -328,7 +318,7 @@ public class ViidController {
faceSampleMapper.updateScore(faceSample.getId(), addFaceResp.getScore()); faceSampleMapper.updateScore(faceSample.getId(), addFaceResp.getScore());
} }
} }
if (Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) { if (deviceConfig != null && Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) {
DynamicTaskGenerator.addTask(faceSample.getId()); DynamicTaskGenerator.addTask(faceSample.getId());
} }
}); });
@@ -338,6 +328,7 @@ 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);
@@ -345,43 +336,12 @@ 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); String filename = StorageUtil.joinPath(PHOTO_PATH, UUID.randomUUID() + "." + ext);
executor.execute(() -> { String _sourceUrl = scenicStorageAdapter.uploadFile(_file, filename);
List<DeviceCropConfig> cropConfigs = deviceConfig._getCropConfig(); scenicStorageAdapter.setAcl(StorageAcl.PUBLIC_READ, filename);
for (DeviceCropConfig cropConfig : cropConfigs) { source.setUrl(_sourceUrl);
source.setId(SnowFlakeUtil.getLongId()); source.setPosJson(JSON.toJSONString(facePosition));
String filename = StorageUtil.joinPath(PHOTO_PATH, UUID.randomUUID() + "." + ext); sourceMapper.add(source);
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);
source.setUrl(_sourceUrl);
source.setPosJson(JSON.toJSONString(facePosition));
sourceMapper.add(source);
}
});
} }
log.info("人脸信息及原图{}张入库成功!设备ID:{}", type14ImageList.size(), deviceID); log.info("人脸信息及原图{}张入库成功!设备ID:{}", type14ImageList.size(), deviceID);
} }

View File

@@ -278,6 +278,7 @@ 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();

View File

@@ -52,9 +52,8 @@ 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 = 120; public static int QRCODE_SIZE = 80;
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;
@@ -107,30 +106,13 @@ 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), textStartY); 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.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), textStartY + scenicLineHeight); 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);
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")) {
@@ -151,7 +133,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.75f); // 设置写入质量为 75% writeParam.setCompressionQuality(0.95f); // 设置写入质量为 95%
} }
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) {

View File

@@ -9,7 +9,6 @@ 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;
@@ -46,9 +45,8 @@ 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 = 150; public static int QRCODE_SIZE = 100;
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;
@@ -84,29 +82,13 @@ 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;
Shape originalClip = g2d.getClip(); g2d.drawImage(qrcodeImage, offsetX, offsetY, newQrcodeWidth, newQrcodeHeight, null);
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, textStartY); g2d.drawString(info.getScenicLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, offsetY + scenicLineHeight + FONT_GLOBAL_OFFSET_PERCENT * scenicLineHeight);
g2d.setFont(datetimeFont); g2d.setFont(datetimeFont);
g2d.setColor(datetimeColor); g2d.setColor(datetimeColor);
g2d.drawString(info.getDatetimeLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, textStartY + scenicLineHeight); g2d.drawString(info.getDatetimeLine(), offsetX + newQrcodeWidth + QRCODE_OFFSET_X, offsetY + scenicLineHeight + dtLineHeight + FONT_GLOBAL_OFFSET_PERCENT * dtLineHeight);
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")) {
@@ -127,7 +109,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.75f); // 设置写入质量为 75% writeParam.setCompressionQuality(0.95f); // 设置写入质量为 95%
} }
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) {

View File

@@ -8,12 +8,7 @@ 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;
@@ -28,24 +23,14 @@ 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 {
@@ -83,22 +68,10 @@ public class AuthInterceptor implements HandlerInterceptor {
JwtInfo jwtInfo; JwtInfo jwtInfo;
try { try {
jwtInfo = JwtTokenUtil.parsingToken(token); jwtInfo = JwtTokenUtil.parsingToken(token);
if (StringUtils.equals(jwtInfo.getRoleId(), MERCHANT.type)) { // LocalDateTime expireTime = jwtInfo.getExpireTime();
Long merchantId = jwtInfo.getUserId(); // if (LocalDateTime.now(ZoneId.systemDefault()).isAfter(expireTime)) {
ScenicAccountEntity account = scenicAccountMapper.findAccountById(merchantId.toString()); // throw new TokenExpireException("token过期");
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()));

View File

@@ -25,6 +25,4 @@ 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);
} }

View File

@@ -1,14 +0,0 @@
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);
}

View File

@@ -1,11 +0,0 @@
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);
}

View File

@@ -2,7 +2,6 @@ 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;
@@ -16,6 +15,18 @@ public interface MenuMapper {
* @return * @return
*/ */
int deleteRoleMenuByRoleId(@Param("id")String roleId); int deleteRoleMenuByRoleId(@Param("id")String roleId);
int addRoleMenu(@Param("id")String roleId,@Param("menuStr") String menuStr, @Param("permStr") String permStr); int addRoleMenu(@Param("id")String roleId,@Param("list") List<Integer> list);
RolePermissionResp getPermissionByRoleId(Long roleId); int add(MenuEntity menuEntity);
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);
} }

View File

@@ -21,6 +21,4 @@ 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);
} }

View File

@@ -57,7 +57,6 @@ 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);
@@ -69,7 +68,6 @@ 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);

View File

@@ -1,35 +0,0 @@
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;
}

View File

@@ -1,45 +0,0 @@
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;
}

View File

@@ -1,17 +0,0 @@
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;
}

View File

@@ -1,18 +0,0 @@
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;
}
}

View File

@@ -1,10 +0,0 @@
package com.ycwl.basic.model.aio.resp;
import lombok.Data;
@Data
public class AioDeviceCreateOrderResp {
private boolean skipPay;
private Long orderId;
private String payCode;
}

View File

@@ -1,15 +0,0 @@
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;
}

View File

@@ -19,8 +19,6 @@ 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("景区名称")
@@ -43,7 +41,6 @@ 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;
} }

View File

@@ -1,28 +0,0 @@
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;
}

View File

@@ -34,6 +34,4 @@ 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;
} }

View File

@@ -2,15 +2,12 @@ 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 Long roleId; private String roleId;
private String typeName; private String typeName;
private Date updateAt;
} }

View File

@@ -17,5 +17,6 @@ public class LoginRespVO {
private String name; private String name;
@ApiModelProperty(value = "角色名") @ApiModelProperty(value = "角色名")
private String typeName; private String typeName;
private boolean superAdmin; @ApiModelProperty(value = "菜单列表")
private List<MenuNode> menuNodeList;
} }

View File

@@ -1,15 +1,11 @@
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")
@@ -66,18 +62,4 @@ 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());
}
} }

View File

@@ -1,13 +0,0 @@
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;
}

View File

@@ -26,6 +26,5 @@ 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;
} }

View File

@@ -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;
private List<String> permissions; @ApiModelProperty(value = "菜单ID列表")
private List<String> menus; private List<Integer> menuIdList;
} }

View File

@@ -1,10 +0,0 @@
package com.ycwl.basic.model.pc.role.resp;
import lombok.Data;
@Data
public class RolePermissionResp {
private String roleId;
private String permStr;
private String menuStr;
}

View File

@@ -93,7 +93,4 @@ public class ScenicConfigEntity {
private String videoSourcePackHint; private String videoSourcePackHint;
private String extraNotificationTime; private String extraNotificationTime;
private Integer photoFreeNum;
private Integer videoFreeNum;
} }

View File

@@ -15,7 +15,6 @@ 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;
@@ -56,7 +55,6 @@ 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 {
@@ -68,9 +66,6 @@ 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();
@@ -82,15 +77,12 @@ 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;
public Config getConfig() { private 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()
@@ -134,9 +126,6 @@ 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);
@@ -276,7 +265,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 || refund.getStatus() == PROCESSING) { if (refund.getStatus() == SUCCESS) {
resp.setSuccess(true); resp.setSuccess(true);
resp.setRefundNo(refund.getOutRefundNo()); resp.setRefundNo(refund.getOutRefundNo());
} else { } else {

View File

@@ -11,5 +11,4 @@ public class WxMpPayConfig {
private String wxPublicKeyId; private String wxPublicKeyId;
private String serialNumber; private String serialNumber;
private String apiV3Key; private String apiV3Key;
private boolean enableProfitSharing;
} }

View File

@@ -8,8 +8,6 @@ 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;
@@ -54,21 +52,6 @@ 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);
} }

View File

@@ -1,9 +0,0 @@
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);
}

View File

@@ -1,104 +0,0 @@
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;
}
}

View File

@@ -29,8 +29,6 @@ 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
*/ */
@@ -118,7 +116,6 @@ 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<>();

View File

@@ -11,24 +11,19 @@ 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;
@@ -51,12 +46,6 @@ 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) {
@@ -99,7 +88,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, scenicAccount.getUpdateTime()); String token = jwtTokenUtil.generateToken(jwtInfo);
ScenicLoginRespVO scenicLoginRespVO = new ScenicLoginRespVO(); ScenicLoginRespVO scenicLoginRespVO = new ScenicLoginRespVO();
BeanUtil.copyProperties(scenicAccount,scenicLoginRespVO); BeanUtil.copyProperties(scenicAccount,scenicLoginRespVO);
@@ -116,40 +105,6 @@ 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);
} }
} }

View File

@@ -370,14 +370,14 @@ public class AppStatisticsServiceImpl implements AppStatisticsService {
//当前周期的推送订阅人数 //当前周期的推送订阅人数
vo.setNowPushOfPeopleNum(data.getPushOfMemberNum()); vo.setNowPushOfPeopleNum(data.getPushOfMemberNum());
//当前周期的预览视频人数 //当前周期的预览视频人数
vo.setNowPreviewVideoOfPeopleNum(data.getPreviewVideoOfMemberNum()); vo.setNowPreviewVideoOfPeopleNum(data.getPreviewOfVideoNum());
}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.getPreviewVideoOfMemberNum()); vo.setPreviousPreviewVideoOfPeopleNum(data.getPreviewOfVideoNum());
} }
} }

View File

@@ -75,6 +75,8 @@ 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;
@@ -85,6 +87,8 @@ 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;
@@ -94,18 +98,10 @@ 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(scenicId); videoReqQuery.setScenicId(query.getScenicId());
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()));
@@ -125,21 +121,25 @@ public class GoodsServiceImpl implements GoodsService {
}); });
SourceReqQuery sourceReqQuery = new SourceReqQuery(); SourceReqQuery sourceReqQuery = new SourceReqQuery();
sourceReqQuery.setScenicId(scenicId); sourceReqQuery.setScenicId(query.getScenicId());
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(scenicId); ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(query.getScenicId());
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)) {
return !Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo()); if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
return false;
}
} else if (Integer.valueOf(2).equals(type)) { } else if (Integer.valueOf(2).equals(type)) {
return !Integer.valueOf(1).equals(scenicConfig.getDisableSourceImage()); if (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;
}); });
}).toList(); }).collect(Collectors.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(face.getScenicId()); sourceReqQuery.setScenicId(query.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(face.getId()); sourceReqQuery.setFaceId(query.getFaceId());
List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery); List<SourceRespVO> list = sourceMapper.listUser(sourceReqQuery);
List<GoodsDetailVO> goodsDetailVOList = new ArrayList<>(); List<GoodsDetailVO> goodsDetailVOList = new ArrayList<>();
@@ -195,7 +195,6 @@ 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) {
@@ -206,7 +205,6 @@ 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());
@@ -279,9 +277,6 @@ 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()));
@@ -516,11 +511,11 @@ public class GoodsServiceImpl implements GoodsService {
} }
Integer sourceType = query.getSourceType(); Integer sourceType = query.getSourceType();
SourceReqQuery sourceReqQuery = new SourceReqQuery(); SourceReqQuery sourceReqQuery = new SourceReqQuery();
sourceReqQuery.setScenicId(face.getScenicId()); sourceReqQuery.setScenicId(query.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(face.getId()); sourceReqQuery.setFaceId(query.getFaceId());
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 -> {
@@ -540,7 +535,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(), face.getScenicId(), query.getSourceType(), face.getId()); IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), query.getScenicId(), query.getSourceType(), query.getFaceId());
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)) {
@@ -612,7 +607,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())).toList(); list = list.stream().filter(source -> source.getId().equals(query.getGoodsId())).collect(Collectors.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 -> {
@@ -633,8 +628,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();
} }
@@ -653,7 +648,7 @@ public class GoodsServiceImpl implements GoodsService {
log.warn("未配置小程序参数,无法生成二维码"); log.warn("未配置小程序参数,无法生成二维码");
return defaultUrlList; return defaultUrlList;
} }
if (scenicConfig != null && scenicConfig.getWatermarkType() != null && !isBuy.isBuy()) { if (scenicConfig != null && scenicConfig.getWatermarkType() != null) {
ImageWatermarkOperatorEnum type = ImageWatermarkOperatorEnum.getByCode(scenicConfig.getWatermarkType()); ImageWatermarkOperatorEnum type = ImageWatermarkOperatorEnum.getByCode(scenicConfig.getWatermarkType());
if (type != null) { if (type != null) {
IStorageAdapter adapter; IStorageAdapter adapter;
@@ -667,7 +662,8 @@ 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 {
WxMpUtil.generateUnlimitedWXAQRCode(scenicMpConfig.getAppId(), scenicMpConfig.getAppSecret(), "pages/videoSynthesis/from_face", face.getId().toString(), qrcode); String urlLink = WxMpUtil.generateUrlLink(scenicMpConfig.getAppId(), scenicMpConfig.getAppSecret(), "pages/videoSynthesis/index", "scenicId=" + face.getScenicId() + "&faceId=" + face.getId());
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;
@@ -737,7 +733,7 @@ public class GoodsServiceImpl implements GoodsService {
} }
Integer sourceType = query.getSourceType(); Integer sourceType = query.getSourceType();
SourceReqQuery sourceReqQuery = new SourceReqQuery(); SourceReqQuery sourceReqQuery = new SourceReqQuery();
sourceReqQuery.setScenicId(face.getScenicId()); sourceReqQuery.setScenicId(query.getScenicId());
sourceReqQuery.setIsBuy(query.getIsBuy()); sourceReqQuery.setIsBuy(query.getIsBuy());
sourceReqQuery.setMemberId(face.getMemberId()); sourceReqQuery.setMemberId(face.getMemberId());
sourceReqQuery.setType(sourceType); sourceReqQuery.setType(sourceType);

View File

@@ -36,6 +36,4 @@ 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);
} }

View File

@@ -0,0 +1,18 @@
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);
}

View File

@@ -4,14 +4,11 @@ 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);

View File

@@ -21,5 +21,4 @@ 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);
} }

View File

@@ -26,7 +26,6 @@ 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;
@@ -57,17 +56,12 @@ 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());
if (StringUtils.isBlank(addOrUpdateAdminUserReqVO.getPassword())) { // String password = addOrUpdateAdminUserReqVO.getPassword();
return ApiResponse.fail("密码不能为空"); // addOrUpdateAdminUserReqVO.setPassword(password);
}
int add = adminUserMapper.add(addOrUpdateAdminUserReqVO); int add = adminUserMapper.add(addOrUpdateAdminUserReqVO);
if (add > 0) { if (add > 0) {
return ApiResponse.success(null); return ApiResponse.success(null);
@@ -111,7 +105,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("账号不存在或密码错误");
} }
Long roleId = login.getRoleId(); String roleId = login.getRoleId();
Object roleObject = redisTemplate.opsForValue().get(ROLE_STATUS + roleId); Object roleObject = redisTemplate.opsForValue().get(ROLE_STATUS + roleId);
@@ -120,12 +114,27 @@ 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(), ADMIN.type, login.getAccount(), login.getAccount(), null), login.getUpdateAt()); String token = jwtTokenUtil.generateToken(new JwtInfo(login.getStaffName(), login.getStaffId(), roleId, login.getAccount(), login.getAccount(), null));
loginRespVO.setToken(token); loginRespVO.setToken(token);
loginRespVO.setName(login.getStaffName()); loginRespVO.setName(login.getStaffName());
loginRespVO.setTypeName(login.getTypeName()); loginRespVO.setTypeName(login.getTypeName());
loginRespVO.setSuperAdmin(Long.valueOf(1L).equals(login.getStaffId())); loginRespVO.setMenuNodeList(MenuList);
return ApiResponse.success(loginRespVO); return ApiResponse.success(loginRespVO);
} }

View File

@@ -8,7 +8,10 @@ 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;
@@ -18,7 +21,6 @@ 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;
@@ -32,7 +34,6 @@ 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;
@@ -44,7 +45,6 @@ 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,12 +52,11 @@ 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;
@@ -100,8 +99,6 @@ 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) {
@@ -283,72 +280,30 @@ 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());
memberSourceEntity.setIsFree(0); IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), sourceEntity.getType(), faceEntity.getId());
if (deviceConfig != null) { if (isBuy.isBuy()) { // 如果用户买过
if (sourceEntity.getType() == 1) { memberSourceEntity.setIsBuy(1);
if (Integer.valueOf(1).equals(deviceConfig.getVideoFree())) { } else if (isBuy.isFree()) { // 全免费逻辑
memberSourceEntity.setIsFree(1); memberSourceEntity.setIsBuy(1);
} } else {
} else if (sourceEntity.getType() == 2) { memberSourceEntity.setIsBuy(0);
if (Integer.valueOf(1).equals(deviceConfig.getImageFree())) {
memberSourceEntity.setIsFree(1);
}
}
} }
return memberSourceEntity; return memberSourceEntity;
}).collect(Collectors.toList()); }).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()) { 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);
}
if (freeSourceIds.contains(memberSourceEntity.getSourceId())) {
memberSourceEntity.setIsFree(1);
}
}
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;
@@ -381,7 +336,6 @@ 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());
@@ -421,8 +375,6 @@ 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);
@@ -441,14 +393,12 @@ public class FaceServiceImpl implements FaceService {
} else { } else {
sourceImageContent.setIsBuy(0); sourceImageContent.setIsBuy(0);
} }
List<MemberSourceEntity> relations = sourceMapper.listByFaceRelation(faceRespVO.getMemberId(), faceId, 2); List<SourceEntity> sourceEntities = sourceMapper.listImageByFaceRelation(faceRespVO.getMemberId(), faceId);
if (!relations.isEmpty()) { if (!sourceEntities.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())) {
@@ -460,14 +410,12 @@ public class FaceServiceImpl implements FaceService {
} else { } else {
sourceVideoContent.setIsBuy(0); sourceVideoContent.setIsBuy(0);
} }
List<MemberSourceEntity> relations = sourceMapper.listByFaceRelation(faceRespVO.getMemberId(), faceId, 1); List<SourceEntity> sourceEntities = sourceMapper.listVideoByFaceRelation(faceRespVO.getMemberId(), faceId);
if (!relations.isEmpty()) { if (!sourceEntities.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) -> {
@@ -492,10 +440,5 @@ public class FaceServiceImpl implements FaceService {
return ApiResponse.success(contentPageVOS); return ApiResponse.success(contentPageVOS);
} }
@Override
public void bindFace(Long faceId, Long userId) {
}
} }

View File

@@ -0,0 +1,78 @@
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("删除失败");
}
}
}

View File

@@ -8,7 +8,6 @@ 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;
@@ -35,11 +34,6 @@ 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());
@@ -61,22 +55,23 @@ public class RoleServiceImpl implements RoleService {
} }
@Override @Override
public ApiResponse addOrUpdate(AddOrUpdateRoleReqVO vo) { public ApiResponse addOrUpdate(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO) {
String id = vo.getId(); String id = addOrUpdateRoleReqVO.getId();
if(StringUtils.isBlank(id)){ if(StringUtils.isBlank(id)){
String roleId = SnowFlakeUtil.getId(); String roleId = SnowFlakeUtil.getId();
vo.setId(roleId); addOrUpdateRoleReqVO.setId(roleId);
if(roleMapper.add(vo)>0){ if(roleMapper.add(addOrUpdateRoleReqVO)>0){
String menuStr = StringUtils.join(vo.getMenus(), ","); if (addOrUpdateRoleReqVO.getMenuIdList() != null && !addOrUpdateRoleReqVO.getMenuIdList().isEmpty()) {
String permStr = StringUtils.join(vo.getPermissions(), ","); menuMapper.addRoleMenu(roleId, addOrUpdateRoleReqVO.getMenuIdList());
menuMapper.addRoleMenu(roleId, menuStr, permStr); }
return ApiResponse.success(null); return ApiResponse.success(null);
} }
}else { }else {
if(roleMapper.update(vo)>0){ if(roleMapper.update(addOrUpdateRoleReqVO)>0){
String menuStr = StringUtils.join(vo.getMenus(), ","); menuMapper.deleteRoleMenuByRoleId(addOrUpdateRoleReqVO.getId());
String permStr = StringUtils.join(vo.getPermissions(), ","); if (addOrUpdateRoleReqVO.getMenuIdList() != null && !addOrUpdateRoleReqVO.getMenuIdList().isEmpty()) {
menuMapper.addRoleMenu(id, menuStr, permStr); menuMapper.addRoleMenu(addOrUpdateRoleReqVO.getId(), addOrUpdateRoleReqVO.getMenuIdList());
}
return ApiResponse.success(null); return ApiResponse.success(null);
} }
} }

View File

@@ -145,11 +145,6 @@ 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("景区修改失败");
@@ -162,11 +157,6 @@ 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("景区状态修改失败");
@@ -192,11 +182,6 @@ 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("景区配置修改失败");

View File

@@ -7,17 +7,13 @@ 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;
@@ -34,8 +30,6 @@ 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) {
@@ -143,29 +137,4 @@ 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());
}
}
} }

View File

@@ -87,13 +87,13 @@ public class TaskFaceServiceImpl implements TaskFaceService {
@Override @Override
public SearchFaceRespVo searchFace(Long faceId) { public SearchFaceRespVo searchFace(Long faceId) {
FaceRespVO face = faceMapper.getById(faceId); FaceRespVO faceRespVO = faceMapper.getById(faceId);
if (face == null) { if (faceRespVO == null) {
SearchFaceRespVo vo = new SearchFaceRespVo(); SearchFaceRespVo vo = new SearchFaceRespVo();
vo.setSampleListIds(new ArrayList<>()); vo.setSampleListIds(new ArrayList<>());
return vo; return vo;
} }
Long scenicId = face.getScenicId(); Long scenicId = faceRespVO.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(), face.getFaceUrl(), "系统定时任务检索"); SearchFaceRespVo respVo = searchFace(faceBodyAdapter, scenicId.toString(), faceRespVO.getFaceUrl(), "系统定时任务检索");
if (respVo != null) { if (respVo != null) {
FaceEntity faceEntity = new FaceEntity(); FaceEntity faceEntity = new FaceEntity();
faceEntity.setId(faceId); faceEntity.setId(faceId);
@@ -120,9 +120,17 @@ 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(face.getMemberId()); memberSourceEntity.setMemberId(faceRespVO.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) {
@@ -138,21 +146,11 @@ 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 = face.getMemberId(); task.memberId = faceRespVO.getMemberId();
VideoPieceGetter.addTask(task); VideoPieceGetter.addTask(task);
} }
} }

View File

@@ -175,7 +175,6 @@ 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();
@@ -446,10 +445,6 @@ 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 的检查

View File

@@ -33,37 +33,25 @@ 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 volatile AliOssStorageConfig config; private 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() {
AliOssStorageConfig currentConfig = this.config; return config.identity();
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 newConfig = new AliOssStorageConfig(); AliOssStorageConfig config = new AliOssStorageConfig();
newConfig.setAccessKeyId(_config.get("accessKeyId")); config.setAccessKeyId(_config.get("accessKeyId"));
newConfig.setAccessKeySecret(_config.get("accessKeySecret")); config.setAccessKeySecret(_config.get("accessKeySecret"));
newConfig.setBucketName(_config.get("bucketName")); config.setBucketName(_config.get("bucketName"));
newConfig.setEndpoint(_config.get("endpoint")); config.setEndpoint(_config.get("endpoint"));
newConfig.setRegion(_config.get("region")); config.setRegion(_config.get("region"));
newConfig.setUrl(_config.get("url")); config.setUrl(_config.get("url"));
newConfig.setPrefix(_config.get("prefix")); config.setPrefix(_config.get("prefix"));
newConfig.checkEverythingOK(); config.checkEverythingOK();
this.config = config;
synchronized (configLock) {
this.config = newConfig;
// 配置更新后,需要重置客户端连接
resetClient();
}
} }
@Override @Override
@@ -71,14 +59,10 @@ 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) {
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
}
synchronized (configLock) {
this.config = (AliOssStorageConfig) config; this.config = (AliOssStorageConfig) config;
// 配置更新后,需要重置客户端连接 } else {
resetClient(); throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
} }
} }
@@ -91,25 +75,12 @@ 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 ossClient.putObject(putObjectRequest);
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);
}
return getUrl(path); return getUrl(path);
} catch (Exception e) { } catch (Exception e) {
throw new UploadFileFailedException("上传文件失败:" + e.getMessage()); throw new UploadFileFailedException("上传文件失败:" + e.getMessage());
@@ -121,11 +92,7 @@ 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();
AliOssStorageConfig currentConfig = this.config; ossClient.deleteObject(config.getBucketName(), buildPath(path));
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;
@@ -134,22 +101,14 @@ final public class AliOssAdapter extends AStorageAdapter {
@Override @Override
public String getUrl(String... path) { public String getUrl(String... path) {
AliOssStorageConfig currentConfig = this.config; return config.getUrl() + "/" + buildPath(path);
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();
AliOssStorageConfig currentConfig = this.config; URL url = ossClient.generatePresignedUrl(config.getBucketName(), buildPath(path), expireDate, HttpMethod.GET);
if (currentConfig == null) {
throw new StorageConfigException("存储适配器未配置");
}
URL url = ossClient.generatePresignedUrl(currentConfig.getBucketName(), buildPath(path), expireDate, HttpMethod.GET);
return url.toString(); return url.toString();
} }
} }
@@ -158,11 +117,7 @@ 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();
AliOssStorageConfig currentConfig = this.config; GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(config.getBucketName(), buildPath(path), HttpMethod.PUT);
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);
} }
@@ -174,11 +129,7 @@ final public class AliOssAdapter extends AStorageAdapter {
@Override @Override
public List<StorageFileObject> listDir(String... path) { public List<StorageFileObject> listDir(String... path) {
AliOssStorageConfig currentConfig = this.config; ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName());
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;
@@ -229,11 +180,7 @@ 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;
AliOssStorageConfig currentConfig = this.config; DeleteObjectsRequest request = new DeleteObjectsRequest(config.getBucketName());
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);
@@ -261,11 +208,7 @@ 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();
AliOssStorageConfig currentConfig = this.config; ossClient.setObjectAcl(config.getBucketName(), buildPath(path), convertAcl(acl));
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;
@@ -276,85 +219,32 @@ 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();
AliOssStorageConfig currentConfig = this.config; return ossClient.doesObjectExist(config.getBucketName(), buildPath(path));
if (currentConfig == null) {
return false;
}
return ossClient.doesObjectExist(currentConfig.getBucketName(), buildPath(path));
} }
} }
private OSSWrapper getOssClient() { private OSSWrapper getOssClient() {
AliOssStorageConfig currentConfig = this.config; OSS ossClient = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
if (currentConfig == null) { return new OSSWrapper(ossClient);
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) {
AliOssStorageConfig currentConfig = this.config; if (StringUtils.isNotBlank(config.getPrefix())) {
if (currentConfig != null && StringUtils.isNotBlank(currentConfig.getPrefix())) { return StorageUtil.joinPath(config.getPrefix(), paths);
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) {
AliOssStorageConfig currentConfig = this.config; return StorageUtil.getRelativePath(path, config.getPrefix());
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;
} }
// 提供对原始对象的方法访问 // 提供对原始对象的方法访问
@@ -364,10 +254,8 @@ final public class AliOssAdapter extends AStorageAdapter {
@Override @Override
public void close() { public void close() {
// 只有非共享客户端才自动关闭 // 在此处实现资源关闭逻辑(如调用 OSS 的关闭方法)
if (autoClose && ossClient != null) { ossClient.shutdown(); // 假设 OSS 提供 shutdown 方法关闭资源
ossClient.shutdown();
}
} }
} }
} }

View File

@@ -26,37 +26,25 @@ 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 volatile AwsOssStorageConfig config; private 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() {
AwsOssStorageConfig currentConfig = this.config; return config.identity();
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 newConfig = new AwsOssStorageConfig(); AwsOssStorageConfig config = new AwsOssStorageConfig();
newConfig.setAccessKeyId(_config.get("accessKeyId")); config.setAccessKeyId(_config.get("accessKeyId"));
newConfig.setAccessKeySecret(_config.get("accessKeySecret")); config.setAccessKeySecret(_config.get("accessKeySecret"));
newConfig.setBucketName(_config.get("bucketName")); config.setBucketName(_config.get("bucketName"));
newConfig.setEndpoint(_config.get("endpoint")); config.setEndpoint(_config.get("endpoint"));
newConfig.setRegion(_config.get("region")); config.setRegion(_config.get("region"));
newConfig.setUrl(_config.get("url")); config.setUrl(_config.get("url"));
newConfig.setPrefix(_config.get("prefix")); config.setPrefix(_config.get("prefix"));
newConfig.checkEverythingOK(); config.checkEverythingOK();
this.config = config;
synchronized (configLock) {
this.config = newConfig;
// 配置更新后,需要重置客户端连接
resetClient();
}
} }
@Override @Override
@@ -64,14 +52,10 @@ 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) {
throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
}
synchronized (configLock) {
this.config = (AwsOssStorageConfig) config; this.config = (AwsOssStorageConfig) config;
// 配置更新后,需要重置客户端连接 } else {
resetClient(); throw new StorageConfigException("配置类型错误,传入的类为:" + config.getClass().getName());
} }
} }
@@ -84,22 +68,13 @@ 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 putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead); // 设置访问权限,让所有用户都允许访问
try (InputStream byteInputStream = new java.io.ByteArrayInputStream(bytes)) { s3Client.putObject(putObjectRequest);
PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), fullPath, byteInputStream, metadata);
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead); // 设置访问权限,让所有用户都允许访问
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());
@@ -175,7 +150,6 @@ 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());
@@ -246,57 +220,14 @@ public class AwsOssAdapter extends AStorageAdapter {
} }
private S3Wrapper getS3Client() { private S3Wrapper getS3Client() {
AwsOssStorageConfig currentConfig = this.config; BasicAWSCredentials basicAwsCred = new BasicAWSCredentials(config.getAccessKeyId(), config.getAccessKeySecret());
if (currentConfig == null) { ClientConfiguration clientConfiguration = new ClientConfiguration();
throw new StorageConfigException("存储适配器未配置"); clientConfiguration.setProtocol(Protocol.HTTPS);
} AmazonS3Client s3 = new AmazonS3Client(basicAwsCred,clientConfiguration);
S3ClientOptions options = S3ClientOptions.builder().setPathStyleAccess(true).setPayloadSigningEnabled(true).disableChunkedEncoding().build();
if (s3Client == null) { s3.setS3ClientOptions(options);
synchronized (clientLock) { s3.setEndpoint(config.getEndpoint());
if (s3Client == null) { return new S3Wrapper(s3);
// 在同步块内再次检查配置,确保配置一致性
currentConfig = this.config;
if (currentConfig == null) {
throw new StorageConfigException("存储适配器未配置");
}
BasicAWSCredentials basicAwsCred = new BasicAWSCredentials(
currentConfig.getAccessKeyId(),
currentConfig.getAccessKeySecret()
);
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setProtocol(Protocol.HTTPS);
s3Client = new AmazonS3Client(basicAwsCred, clientConfiguration);
S3ClientOptions options = S3ClientOptions.builder()
.setPathStyleAccess(true)
.setPayloadSigningEnabled(true)
.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) {
@@ -311,18 +242,10 @@ public class AwsOssAdapter extends AStorageAdapter {
return StorageUtil.getRelativePath(path, config.getPrefix()); return StorageUtil.getRelativePath(path, config.getPrefix());
} }
public record S3Wrapper(AmazonS3Client s3Client, boolean autoClose) implements AutoCloseable { public record S3Wrapper(AmazonS3Client s3Client) implements AutoCloseable {
public S3Wrapper(AmazonS3Client s3Client) {
this(s3Client, true);
}
@Override @Override
public void close() { public void close() {
// 只有非共享客户端才自动关闭 s3Client.shutdown();
if (autoClose && s3Client != null) {
s3Client.shutdown();
}
} }
} }
} }

View File

@@ -3,207 +3,71 @@ 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.nio.file.*; import java.util.Collections;
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 "LOCAL_STORAGE"; return "";
} }
@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) {
if (inputStream == null) { return "";
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 { return false;
String fullPath = buildLocalPath(path);
return Files.deleteIfExists(Paths.get(fullPath));
} catch (IOException e) {
return false;
}
} }
@Override @Override
public String getUrl(String... path) { public String getUrl(String... path) {
String relativePath = buildRelativePath(path); return "";
return baseUrl + "/" + relativePath;
} }
@Override @Override
public String getUrlForDownload(Date expireDate, String... path) { public String getUrlForDownload(Date expireDate, String... path) {
// 本地存储不支持带过期时间的URL,直接返回普通URL return "";
return getUrl(path);
} }
@Override @Override
public String getUrlForUpload(Date expireDate, String contentType, String... path) { public String getUrlForUpload(Date expireDate, String contentType, String... path) {
// 本地存储不支持预签名上传URL return "";
return getUrl(path);
} }
@Override @Override
public List<StorageFileObject> listDir(String... path) { public List<StorageFileObject> listDir(String... path) {
String fullPath = buildLocalPath(path); return Collections.emptyList();
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); return false;
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;
}
} }
@Override @Override
public boolean setAcl(StorageAcl acl, String... path) { public boolean setAcl(StorageAcl acl, String... path) {
// 本地存储不支持ACL设置 return false;
return true;
} }
@Override @Override
public boolean isExists(String... path) { public boolean isExists(String... path) {
String fullPath = buildLocalPath(path); return false;
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;
} }
} }

View File

@@ -131,7 +131,7 @@ public class DynamicTaskGenerator {
return false; return false;
} }
return face.getScenicId().equals(faceSample.getScenicId()); return face.getScenicId().equals(faceSample.getScenicId());
}).toList(); }).collect(Collectors.toList());
if (faceIdList.isEmpty()) { if (faceIdList.isEmpty()) {
log.info("本景区人脸样本ID不在人脸样本库中,忽略任务:{}", task); log.info("本景区人脸样本ID不在人脸样本库中,忽略任务:{}", task);
return; return;

View File

@@ -1,70 +0,0 @@
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);
});
}
}

View File

@@ -7,9 +7,7 @@ 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;
@@ -18,8 +16,6 @@ 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;
@@ -61,8 +57,6 @@ 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;
@@ -74,8 +68,6 @@ 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 {
@@ -216,7 +208,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) {
log.info("executor已中断![A:{}/T:{}/F:{}]", executor.getActiveCount(), executor.getTaskCount(), executor.getCompletedTaskCount()); return;
} finally { } finally {
if (task.faceId != null) { if (task.faceId != null) {
taskStatusBiz.setFaceCutStatus(task.faceId, 1); taskStatusBiz.setFaceCutStatus(task.faceId, 1);
@@ -228,29 +220,6 @@ 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) {

View File

@@ -1,19 +1,14 @@
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(",");
@@ -26,37 +21,6 @@ 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;

View File

@@ -13,8 +13,6 @@ 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;
@@ -51,19 +49,10 @@ 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;
}
/** /**

View File

@@ -3,7 +3,6 @@ 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;
@@ -13,10 +12,8 @@ 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<>();
@@ -34,27 +31,12 @@ public class WxMpUtil {
tokens.remove(appId); tokens.remove(appId);
} }
return tokens.computeIfAbsent(appId, (k) -> { return tokens.computeIfAbsent(appId, (k) -> {
String token; String url = String.format(ACCESS_TOKEN_URL, appId, appSecret);
if (!System.getProperty("os.name").toLowerCase().startsWith("win")) { String response = HttpUtil.get(url);
String url = String.format(STABLE_ACCESS_TOKEN_URL, appId, appSecret); JSONObject jsonObject = JSONObject.parseObject(response);
JSONObject params = new JSONObject(); String token = jsonObject.getString("access_token");
params.put("grant_type", "client_credential"); Date expireTime = new Date(System.currentTimeMillis() + jsonObject.getInteger("expires_in") * 1000 / 2);
params.put("appid", appId); expireTimes.put(appId, expireTime);
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 response = HttpUtil.get(url);
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);
}
return token; return token;
}); });
} finally { } finally {
@@ -84,28 +66,6 @@ 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();

View File

@@ -28,7 +28,6 @@
<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">
@@ -78,8 +77,7 @@
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
@@ -91,16 +89,4 @@
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>

View File

@@ -1,17 +0,0 @@
<?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>

View File

@@ -109,7 +109,6 @@
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

View File

@@ -1,11 +0,0 @@
<?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>

View File

@@ -2,18 +2,75 @@
<!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">
replace role_menu(`role_id`, `menu_str`, `perm_str`, `update_time`) insert into role_menu(`role_id`, `menu_id`)
values (#{id}, #{menuStr}, #{permStr}, NOW()) values
<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>
<select id="getPermissionByRoleId" resultType="com.ycwl.basic.model.pc.role.resp.RolePermissionResp"> <delete id="deleteById">
select role_id, menu_str, perm_str update menu set is_remove=1 where id = #{id}
</delete>
<delete id="deleteRoleMenuByMenuId">
delete
from role_menu from role_menu
where role_id = #{id} where menu_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>

View File

@@ -121,7 +121,6 @@
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
@@ -142,7 +141,6 @@
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

View File

@@ -65,19 +65,6 @@
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>

View File

@@ -9,16 +9,14 @@
<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>

View File

@@ -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 = 2 where ms.type = 1
and s.create_time >= #{start} and s.create_time >= #{start}
and s.create_time &lt;= #{end} and s.create_time &lt;= #{end}
group by s.scenic_id, s.device_id, ms.face_id group by s.scenic_id, s.device_id, ms.face_id

View File

@@ -126,9 +126,7 @@
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>

View File

@@ -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<if test="isFree">, is_free</if>) replace member_source(scenic_id, face_id, member_id, source_id, is_buy, type, order_id, is_free)
values (#{scenicId}, #{faceId}, #{memberId}, #{sourceId}, #{isBuy}, #{type}, #{orderId}<if test="isFree">, #{isFree}</if>) values (#{scenicId}, #{faceId}, #{memberId}, #{sourceId}, #{isBuy}, #{type}, #{orderId}, #{isFree})
</insert> </insert>
<insert id="addRelations"> <insert id="addRelations">
insert IGNORE 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, 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,14 +42,6 @@
</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>
@@ -235,11 +227,4 @@
<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>

View File

@@ -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 pay_at >= #{startTime} and create_at >= #{startTime}
</if> </if>
<if test="endTime!= null"> <if test="endTime!= null">
and pay_at &lt;= #{endTime} and create_at &lt;= #{endTime}
</if> </if>
</select> </select>
<select id="countPreviewVideoOfMember" resultType="java.lang.Integer"> <select id="countPreviewVideoOfMember" resultType="java.lang.Integer">
@@ -61,20 +61,17 @@
SELECT SELECT
IFNULL(count(1), 0) AS count IFNULL(count(1), 0) AS count
FROM ( FROM (
select 1 select count(1) as count
FROM `t_stats_record` r from `order`
left join `t_stats` s on r.trace_id=s.trace_id where scenic_id = #{scenicId}
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 s.create_time >= #{startTime} and create_at >= #{startTime}
</if> </if>
<if test="endTime!= null"> <if test="endTime!= null">
and s.create_time &lt;= #{endTime} and create_at &lt;= #{endTime}
</if> </if>
group by s.member_id group by member_id
) AS subquery; )a
</select> </select>
<select id="countPayOfMember" resultType="java.lang.Integer"> <select id="countPayOfMember" resultType="java.lang.Integer">
SELECT SELECT

View File

@@ -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, sort, 0 as sourceType,
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: 1.3 MiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -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("38e1285c-84d0-464a-810d-053e9502e257.jpg")); info.setOriginalFile(new File("e2d32de7-6e85-4e07-b42f-477347073539.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日 留念");