From 7c2d6571c192c8873820dc034052ea06fb145820 Mon Sep 17 00:00:00 2001 From: haozq <1611483981@qq.com> Date: Sat, 16 Aug 2025 16:22:19 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=83=E5=8B=A4=E5=87=BA=E5=85=A5=E5=9C=BA?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/api/RemoteUakUtilsService.java | 14 +- .../system/api/RemoteUploadUtilsService.java | 21 +- .../com/bonus/system/api/domain/FileVo.java | 35 ++ .../RemoteUakUtilsFallbackFactory.java | 5 + .../RemoteUploadUtilsFallbackFactory.java | 8 +- .../file/controller/FileUtilController.java | 20 +- bonus-modules/bonus-urk/pom.xml | 6 +- .../java/com/bonus/urk/config/RedisUtils.java | 107 ---- .../urk/controller/SendUserController.java | 10 +- .../java/com/bonus/urk/handle/ReceiveCmd.java | 9 +- .../com/bonus/urk/handle/ResultHandle.java | 2 + .../com/bonus/urk/handle/UserFaceHandle.java | 26 +- .../com/bonus/urk/mapper/ResultMapper.java | 28 +- .../com/bonus/urk/mapper/SendUserMapper.java | 8 + .../com/bonus/urk/mapper/UrkMinioMapper.java | 61 +++ .../urk/mapper/UserFaceHandleMapper.java | 13 + .../com/bonus/urk/minio/UrkMinioConfig.java | 45 ++ .../com/bonus/urk/minio/UrkMinioService.java | 431 ++++++++++++++++ .../com/bonus/urk/minio/UrkMinioUtil.java | 480 ++++++++++++++++++ .../com/bonus/urk/service/ResultService.java | 67 ++- .../bonus/urk/service/SendUserService.java | 48 ++ .../com/bonus/urk/service/TaskService.java | 26 +- .../urk/service/UserFaceHandleService.java | 39 +- .../com/bonus/urk/servlet/DeviceServlet.java | 22 +- .../java/com/bonus/urk/vo/KqDevUserIdVo.java | 23 + .../src/main/resources/bootstrap-local.yml | 10 +- .../resources/mapper/urk/ResultMapper.xml | 35 +- .../resources/mapper/urk/SendUserMapper.xml | 6 + .../resources/mapper/urk/UrkMinioMapper.xml | 79 +++ .../mapper/urk/UserFaceHandleMapper.xml | 19 +- 30 files changed, 1503 insertions(+), 200 deletions(-) create mode 100644 bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/FileVo.java delete mode 100644 bonus-modules/bonus-urk/src/main/java/com/bonus/urk/config/RedisUtils.java create mode 100644 bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UrkMinioMapper.java create mode 100644 bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioConfig.java create mode 100644 bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioService.java create mode 100644 bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioUtil.java create mode 100644 bonus-modules/bonus-urk/src/main/java/com/bonus/urk/vo/KqDevUserIdVo.java create mode 100644 bonus-modules/bonus-urk/src/main/resources/mapper/urk/UrkMinioMapper.xml diff --git a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUakUtilsService.java b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUakUtilsService.java index 2782fa1..acc2ec8 100644 --- a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUakUtilsService.java +++ b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUakUtilsService.java @@ -36,13 +36,23 @@ public interface RemoteUakUtilsService { /** * 新增考勤机触发 * @param deviceCode - * @param userId + * @param proId * @param source */ @PostMapping(value = "/business/getUserSendToDev") - public void getUserSendToDev(@RequestParam(value = "deviceCode") String deviceCode, @RequestParam(value = "userId")int userId, + public void getUserSendToDev(@RequestParam(value = "deviceCode") String deviceCode, @RequestParam(value = "proId")int proId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + /** + * 考勤机解绑 + * @param userId + * @param proId + * @param source + */ + @PostMapping(value = "/business/delDevByProId") + public void delDevByProId(@RequestParam(value = "userId") int userId, @RequestParam(value = "proId")int proId, + @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + /** * 人员出场触发 * @param userId diff --git a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUploadUtilsService.java b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUploadUtilsService.java index 3dd857b..aefc164 100644 --- a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUploadUtilsService.java +++ b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/RemoteUploadUtilsService.java @@ -3,16 +3,13 @@ package com.bonus.system.api; import com.bonus.common.core.constant.SecurityConstants; import com.bonus.common.core.constant.ServiceNameConstants; import com.bonus.common.core.domain.R; -import com.bonus.common.core.web.domain.AjaxResult; -import com.bonus.system.api.factory.RemoteFileFallbackFactory; + +import com.bonus.system.api.domain.FileVo; import com.bonus.system.api.factory.RemoteUploadUtilsFallbackFactory; import com.bonus.system.api.model.UploadFileVo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -62,20 +59,12 @@ public interface RemoteUploadUtilsService { , @RequestHeader(SecurityConstants.FROM_SOURCE) String source); /** - * @param bast64 单文件上传 - * @param sourceTable 资源表 -必填 - * @param sourceId 资源表id -必填 - * @param sourceType 数据类型 -非必填 - * @param prefix -文件存储路径文件架名称 -非必填 - * @param bucketName -存储桶名称 -非必填 + * FileVo * @param source -内部接口 SecurityConstants.INNER * @return */ @PostMapping(value = "/uploadFile/uploadBast64") - public R uploadBast64(@RequestParam(value = "bast64") String bast64, @RequestParam(value = "sourceTable")String sourceTable, - @RequestParam(value = "sourceId")String sourceId, @RequestParam(value = "sourceType")String sourceType, - @RequestParam(value = "prefix")String prefix, @RequestParam(value = "bucketName")String bucketName - , @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + public R uploadBast64(@RequestBody FileVo fileVo, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); /** * 多文件上传-bast64 * @param bast64 必填 diff --git a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/FileVo.java b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/FileVo.java new file mode 100644 index 0000000..53d453d --- /dev/null +++ b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/domain/FileVo.java @@ -0,0 +1,35 @@ +package com.bonus.system.api.domain; + +import com.bonus.common.core.web.domain.BaseEntity; +import lombok.Data; + +/** + * @author 黑子 + */ +@Data +public class FileVo extends BaseEntity{ + + private String bast64; + + private String sourceTable; + + private String sourceType; + + private String prefix; + + private String bucketName; + + private String sourceId; + + public FileVo() { + } + + public FileVo(String bast64, String sourceTable, String sourceType, String prefix, String bucketName, String sourceId) { + this.bast64 = bast64; + this.sourceTable = sourceTable; + this.sourceType = sourceType; + this.prefix = prefix; + this.bucketName = bucketName; + this.sourceId = sourceId; + } +} diff --git a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/factory/RemoteUakUtilsFallbackFactory.java b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/factory/RemoteUakUtilsFallbackFactory.java index 39a063f..9021e2f 100644 --- a/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/factory/RemoteUakUtilsFallbackFactory.java +++ b/bonus-api/bonus-api-system/src/main/java/com/bonus/system/api/factory/RemoteUakUtilsFallbackFactory.java @@ -37,6 +37,11 @@ public class RemoteUakUtilsFallbackFactory implements FallbackFactory uploadBast64(String bast64, String sourceTable, String sourceId, String sourceType, String prefix, String bucketName, String source) { - return R.fail("bast64文件上传失败:" + throwable.getMessage()); + public R uploadBast64(@RequestBody FileVo fileVo, String source) { + return null; } + @Override public R> uploadBast64List(String[] bast64, String sourceTable, String sourceId, String[] sourceType, String prefix, String bucketName, String source) { return R.fail("bast64多文件上传失败:" + throwable.getMessage()); diff --git a/bonus-modules/bonus-file/src/main/java/com/bonus/file/controller/FileUtilController.java b/bonus-modules/bonus-file/src/main/java/com/bonus/file/controller/FileUtilController.java index 9728acf..43d2c1e 100644 --- a/bonus-modules/bonus-file/src/main/java/com/bonus/file/controller/FileUtilController.java +++ b/bonus-modules/bonus-file/src/main/java/com/bonus/file/controller/FileUtilController.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import com.bonus.common.core.domain.R; import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.file.service.impl.FileUtilsServiceImpl; +import com.bonus.system.api.domain.FileVo; import com.bonus.system.api.domain.SysFile; import com.bonus.system.api.model.UploadFileVo; import io.swagger.annotations.Api; @@ -12,6 +13,7 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; 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.RestController; import org.springframework.web.multipart.MultipartFile; @@ -62,28 +64,24 @@ public class FileUtilController { } /** * - * @param sourceTable 表名称 - - * @param sourceId 表id - * @param sourceType 文件类型 - * @param prefix 文件路径前缀 - * @param bast64 + * @param vo * @return */ @PostMapping("uploadBast64") - public R upload(String bast64,String sourceTable,String sourceId,String sourceType,String prefix,String bucketName) { + public R upload(@RequestBody FileVo vo) { try { - if (ObjectUtil.isEmpty(sourceTable)) { + if (ObjectUtil.isEmpty(vo.getSourceTable())) { return R.fail("资源表不能为空"); } - if (ObjectUtil.isEmpty(sourceId)) { + if (ObjectUtil.isEmpty(vo.getSourceId())) { return R.fail("资源id不能为空"); } // 上传并返回访问地址 - if (ObjectUtil.isEmpty(bast64)) { + if (ObjectUtil.isEmpty(vo.getBast64())) { return R.fail("文件不能为空"); } - UploadFileVo vo= service.upload( sourceTable,sourceId,sourceType,prefix,bast64,bucketName); - return R.ok(vo); + UploadFileVo uploadFileVo= service.upload( vo.getSourceTable(),vo.getSourceId(),vo.getSourceType(),vo.getPrefix(),vo.getBast64(),vo.getBucketName()); + return R.ok(uploadFileVo); } catch (Exception e) { log.error(e.toString(),e); diff --git a/bonus-modules/bonus-urk/pom.xml b/bonus-modules/bonus-urk/pom.xml index 010d143..bcf7819 100644 --- a/bonus-modules/bonus-urk/pom.xml +++ b/bonus-modules/bonus-urk/pom.xml @@ -86,7 +86,11 @@ 30.0-jre compile - + + io.minio + minio + 8.5.12 + org.springframework spring-context diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/config/RedisUtils.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/config/RedisUtils.java deleted file mode 100644 index 506ab9d..0000000 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/config/RedisUtils.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.bonus.urk.config; - -import com.google.gson.Gson; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.*; -import org.springframework.stereotype.Component; - -import java.util.concurrent.TimeUnit; - -/** - * Redis工具类 - * - * @author eqzcy@163.com - */ -@Component -public class RedisUtils { - @Autowired - private RedisTemplate redisTemplate; - @Autowired - private ValueOperations valueOperations; - @Autowired - private HashOperations hashOperations; - @Autowired - private ListOperations listOperations; - @Autowired - private SetOperations setOperations; - @Autowired - private ZSetOperations zSetOperations; - /** 默认过期时长,单位:秒 */ - public final static long DEFAULT_EXPIRE = 60 * 60 * 24; - /** 不设置过期时长 */ - public final static long NOT_EXPIRE = -1; - private final static Gson gson = new Gson(); - - public void set(String key, Object value, long expire){ - valueOperations.set(key, toJson(value)); - if(expire != NOT_EXPIRE){ - redisTemplate.expire(key, expire, TimeUnit.SECONDS); - } - } - - public void set(String key, Object value){ - set(key, value, DEFAULT_EXPIRE); - } - - public T get(String key, Class clazz, long expire) { - String value = valueOperations.get(key); - if(expire != NOT_EXPIRE){ - redisTemplate.expire(key, expire, TimeUnit.SECONDS); - } - return value == null ? null : fromJson(value, clazz); - } - - public T get(String key, Class clazz) { - return get(key, clazz, NOT_EXPIRE); - } - - public String get(String key, long expire) { - String value = valueOperations.get(key); - if(expire != NOT_EXPIRE){ - redisTemplate.expire(key, expire, TimeUnit.SECONDS); - } - return value; - } - - public String get(String key) { - return get(key, NOT_EXPIRE); - } - - public void delete(String key) { - redisTemplate.delete(key); - } - - /** - * 判断key是否存在 - * - * @param key 键 - * @return true 存在 false不存在 - */ - public boolean hasKey(String key) { - try { - return redisTemplate.hasKey(key); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - - } - - /** - * Object转成JSON数据 - */ - private String toJson(Object object){ - if(object instanceof Integer || object instanceof Long || object instanceof Float || - object instanceof Double || object instanceof Boolean || object instanceof String){ - return String.valueOf(object); - } - return gson.toJson(object); - } - - /** - * JSON数据,转成Object - */ - private T fromJson(String json, Class clazz){ - return gson.fromJson(json, clazz); - } -} diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/controller/SendUserController.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/controller/SendUserController.java index 2dc4b42..b38ee31 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/controller/SendUserController.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/controller/SendUserController.java @@ -49,7 +49,15 @@ public class SendUserController { } } - + @PostMapping("delDevByProId") + public void delDevByProId(String deviceCode,int proId) { + try { + service.delDevByProId(deviceCode,proId); + } + catch (Exception e) { + log.error(e.toString(),e); + } + } /** * 人员出场时触发 diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ReceiveCmd.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ReceiveCmd.java index 64a8b5d..a43d2fc 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ReceiveCmd.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ReceiveCmd.java @@ -24,9 +24,6 @@ import java.util.List; @Slf4j public class ReceiveCmd { - @Autowired - private TaskMapper mapper; - @Autowired private TaskService service; @@ -38,7 +35,7 @@ public class ReceiveCmd { public void dealCmdReceiveHandle(DeviceVo deviceVo, HttpServletRequest req, HttpServletResponse resp){ try{ //查询是否有任务处于未下发状态 - List taskList = mapper.selectCmdTaskList(deviceVo.getDevCode()); + List taskList = service.selectCmdTaskList(deviceVo.getDevCode()); if (CollectionUtil.isEmpty(taskList)) { log.info("设备:{}, 没有执行任务", deviceVo.getDevCode()); resp.addHeader(Constant.DEVICE_HEADER_RESPONSE_CODE, Constant.ERROR_NO_CMD); @@ -47,7 +44,7 @@ public class ReceiveCmd { DeviceTaskVo task = taskList.get(0); // 修改任务状态RUN task.setTransStatus(TaskStatusEnum.RUN.ordinal()); - mapper.updateById(task); + service.updateById(task); //依据不通的指令 进行任务 switch (task.getCmdCode()) { case "SET_TIME": @@ -113,7 +110,7 @@ public class ReceiveCmd { default: task.setMsg("未知指令"); task.setTransStatus(TaskStatusEnum.ERROR.ordinal()); - mapper.updateById(task); + service.updateById(task); break; } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ResultHandle.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ResultHandle.java index 0f6d381..fff8b78 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ResultHandle.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/ResultHandle.java @@ -97,6 +97,8 @@ public class ResultHandle { break; } //更新 ,再进行删除任务记录 + taskVo.setUpdateTime(DateUtils.getTime()); + taskVo.setTransStatus(TaskStatusEnum.COMPLETED.ordinal()); service.updateCmdTaskStatus(taskVo); } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/UserFaceHandle.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/UserFaceHandle.java index 3e08d0b..ad0c8b6 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/UserFaceHandle.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/handle/UserFaceHandle.java @@ -70,15 +70,25 @@ public class UserFaceHandle { //验证用户是否入场 BmWorkerEinUserVo vo=service.getOnUserInfo(userId); if(vo==null){ - log.error("人员未入场"); - return; + vo=new BmWorkerEinUserVo(); + vo.setAttPhoto(bast64); + vo.setAttTime(time); + vo.setDevCode(devCode); + vo.setDevName(deviceVo.getDeviceName()); + vo.setUserId(userId); + service.addWrcUser(vo); + resp.addHeader(Constant.DEVICE_HEADER_RESPONSE_CODE, Constant.OK); + resp.getWriter().write(""); + }else { + vo.setAttPhoto(bast64); + vo.setAttTime(time); + vo.setDevCode(devCode); + vo.setDevName(deviceVo.getDeviceName()); + service.addAttendInfo(vo); + //数据返回 + resp.addHeader(Constant.DEVICE_HEADER_RESPONSE_CODE, Constant.OK); + resp.getWriter().write(""); } - vo.setAttPhoto(bast64); - vo.setAttTime(time); - vo.setDevCode(devCode); - vo.setDevName(deviceVo.getDeviceName()); - service.addAttendInfo(vo); - }catch (Exception e){ log.error(e.toString(),e); } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/ResultMapper.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/ResultMapper.java index b2f83cc..6c36d88 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/ResultMapper.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/ResultMapper.java @@ -1,9 +1,12 @@ package com.bonus.urk.mapper; import com.bonus.urk.vo.KqCmdTaskVo; +import com.bonus.urk.vo.KqDevUserIdVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.util.List; + /** * @author 黑子 * 数据返回 数据 @@ -24,7 +27,7 @@ public interface ResultMapper { */ void updateTaskById(KqCmdTaskVo taskVo); - void updateTaskHisById(KqCmdTaskVo taskVo); + int updateTaskHisById(KqCmdTaskVo taskVo); /** * r任务下发后进行状态跟新· @@ -38,4 +41,27 @@ public interface ResultMapper { * @param taskVo */ void delCmdTaskId(KqCmdTaskVo taskVo); + + /** + * 查询任务下发的人员类别 + * @param id + * @return + */ + List getTaskUser(@Param("id") String id); + + /** + * 考勤设备 + * @param userIds + * @param deviceCode + */ + void insertKqDevUserList(@Param("list") List userIds, @Param("deviceCode") String deviceCode); + + /** + * 删除人员考勤数据 + * @param userIds + * @param deviceCode + */ + void delKqDevUser(@Param("list") List userIds, @Param("deviceCode") String deviceCode); + + void insertKqDevUserList2(@Param("list") List userIds, @Param("deviceCode") String deviceCode); } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/SendUserMapper.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/SendUserMapper.java index 0343576..d563252 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/SendUserMapper.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/SendUserMapper.java @@ -2,6 +2,7 @@ package com.bonus.urk.mapper; import com.bonus.urk.vo.DeviceVo; import com.bonus.urk.vo.KqCmdTaskVo; +import com.bonus.urk.vo.KqDevUserIdVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -88,4 +89,11 @@ public interface SendUserMapper { * @return */ List getOnSiteUserBySh(); + + /** + * 获取设备列表数据 + * @param deviceCode + * @return + */ + List getDevUserId(@Param("deviceCode") String deviceCode); } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UrkMinioMapper.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UrkMinioMapper.java new file mode 100644 index 0000000..8fde40d --- /dev/null +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UrkMinioMapper.java @@ -0,0 +1,61 @@ +package com.bonus.urk.mapper; + +import com.bonus.system.api.model.UploadFileVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author 黑子 + */ +@Mapper +public interface UrkMinioMapper { + /** + * 存储文件 + * @param vo + * @return + */ + int insertUploadFile(UploadFileVo vo); + + /** + * 文件上传 + * @param list + * @return + */ + int insertUploadFileList(@Param("list") List list); + + /** + * 文件集合查询 + * @param id + * @param sourceId + * @param sourceType + * @param sourceTable + * @return + */ + List getFileList(@Param("id") String id,@Param("sourceId") String sourceId, @Param("sourceType")String sourceType, @Param("sourceTable")String sourceTable); + + /** + * 删除文件集合 + * @param id + * @return + */ + int delFileList(@Param("ids") String[] id); + + /** + * 依据id 删除单个数据 + * @param id + * @param sourceId + * @param sourceType + * @param sourceTable + * @return + */ + int delFileListBySourceId(@Param("id")String id,@Param("sourceId")String sourceId, @Param("sourceType")String sourceType, @Param("sourceTable")String sourceTable); + + /** + * 查询数据集合 + * @param id + * @return + */ + List getFileListByIds(@Param("ids") String[] id); +} diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UserFaceHandleMapper.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UserFaceHandleMapper.java index 306c991..f83304d 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UserFaceHandleMapper.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/mapper/UserFaceHandleMapper.java @@ -36,4 +36,17 @@ public interface UserFaceHandleMapper { * @return */ Integer getTodayIsExit(BmWorkerEinUserVo vo); + + /** + * 未入场 + * @param vo + * @return + */ + Integer getTodayNoRootIsExit(BmWorkerEinUserVo vo); + + /** + * 未入场人员 打卡 无效记录 + * @param vo + */ + void addWrcUser(BmWorkerEinUserVo vo); } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioConfig.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioConfig.java new file mode 100644 index 0000000..6215e00 --- /dev/null +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioConfig.java @@ -0,0 +1,45 @@ +package com.bonus.urk.minio; + +import io.minio.MinioClient; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Minio 配置信息 + * + * @author bonus + */ +@Configuration +//@ConditionalOnProperty(name = "storage.type", havingValue = "minio") +@ConfigurationProperties(prefix = "minio") +@Data +public class UrkMinioConfig +{ + /** + * 服务地址 + */ + private String endpoint; + + /** + * 用户名 + */ + private String accessKey; + + /** + * 密码 + */ + private String secretKey; + + /** + * 存储桶名称 + */ + private String bucketName; + + @Bean + public MinioClient getMinioClient() + { + return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build(); + } +} diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioService.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioService.java new file mode 100644 index 0000000..79bb45a --- /dev/null +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioService.java @@ -0,0 +1,431 @@ +package com.bonus.urk.minio; + +import com.bonus.common.core.utils.DateUtils; +import com.bonus.common.core.utils.StringUtils; +import com.bonus.system.api.model.UploadFileVo; +import com.bonus.urk.mapper.UrkMinioMapper; +import org.hibernate.validator.internal.util.StringHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +/** + * @author 黑子 + */ +@Service +public class UrkMinioService { + + + public static String floor="relname"; + + @Autowired + private UrkMinioUtil minioUtils; + + @Autowired + private UrkMinioConfig minioConfig; + + @Autowired + private UrkMinioMapper mapper; + + public UploadFileVo upload(String sourceTable, String sourceId, String sourceType, String prefix, String bast64, String bucketName) { + if(bast64.contains(",")){ + bast64 = bast64.split(",")[1]; + } + UploadFileVo vo=new UploadFileVo(); + vo.setSourceId(sourceId); + vo.setSourceTable(sourceTable); + vo.setSourceType(sourceType); + if(StringHelper.isNullOrEmptyString(prefix)){ + prefix=floor; + } + String originFileName = "bast64"; + String day= DateUtils.getCurrentYear(); + String month=DateUtils.getCurrentMonth(); + String year=DateUtils.getCurrentYear(); + String uuid = StringUtils.randomUUID(); + String suffix=getBase64Type(bast64); + // String suffix=StringUtils.substringAfterLast(originFileName, "."); + // 解码Base64字符串 + byte[] decodedBytes = Base64.getDecoder().decode(bast64); + // 计算文件大小 + int fileSizeInBytes = decodedBytes.length; + double kilobytes = fileSizeInBytes / 1024.0; + long size = (long) kilobytes; + String fileName=uuid+"."+suffix; + String filePath=prefix+"/"+year+"/"+month+"/"+day+"/"+fileName; + vo.setFilePath(filePath); + vo.setOriginFileName(fileName); + vo.setFileName(fileName); + vo.setFileSize(size); + vo.setOriginFileName(originFileName); + if(StringHelper.isNullOrEmptyString(bucketName)){ + bucketName=minioConfig.getBucketName(); + }else{ + minioUtils.createBucket(bucketName); + } + minioUtils.uploadImage(bucketName, bast64,filePath); + vo.setBucketName(bucketName); + String path="/"+bucketName+"/"+filePath; + vo.setPath(path); + vo.setUrl(minioConfig.getEndpoint()); + int num=mapper.insertUploadFile(vo); + if(num>0){ + return vo; + } + return null; + } + + + + + /** + * 文件上传 回显 + * @param sourceTable + * @param sourceId + * @param sourceType + * @param file + * @return + */ + public UploadFileVo upload(String sourceTable, String sourceId, String sourceType, String prefix, MultipartFile file, String bucketName) { + UploadFileVo vo=new UploadFileVo(); + vo.setSourceId(sourceId); + vo.setSourceTable(sourceTable); + vo.setSourceType(sourceType); + if(StringHelper.isNullOrEmptyString(prefix)){ + prefix=floor; + } + String originFileName = file.getOriginalFilename(); + String day= DateUtils.getCurrentYear(); + String month=DateUtils.getCurrentMonth(); + String year=DateUtils.getCurrentYear(); + String uuid = StringUtils.randomUUID(); + String suffix=StringUtils.substringAfterLast(originFileName, "."); + long size= file.getSize(); + String fileName=uuid+"."+suffix; + String filePath=prefix+"/"+year+"/"+month+"/"+day+"/"+fileName; + vo.setFilePath(filePath); + vo.setOriginFileName(fileName); + vo.setFileName(fileName); + vo.setFileSize(size); + vo.setOriginFileName(originFileName); + if(StringHelper.isNullOrEmptyString(bucketName)){ + bucketName=minioConfig.getBucketName(); + }else{ + minioUtils.createBucket(bucketName); + } + minioUtils.uploadFile(bucketName, file,filePath); + vo.setBucketName(bucketName); + String path="/"+bucketName+"/"+filePath; + vo.setPath(path); + vo.setUrl(minioConfig.getEndpoint()); + int num=mapper.insertUploadFile(vo); + if(num>0){ + return vo; + } + return null; + } + /** + * 文件上传 + * @param sourceTable + * @param sourceId + * @param sourceType + * @param prefix + * @param files + * @param bucketName + * @return + */ + public List uploadFile(String sourceTable, String sourceId, String[] sourceType, String prefix, MultipartFile[] files, String bucketName) { + List list=new ArrayList<>(); + if(StringHelper.isNullOrEmptyString(prefix)){ + prefix=floor; + } + String day= DateUtils.getCurrentYear(); + String month=DateUtils.getCurrentMonth(); + String year=DateUtils.getCurrentYear(); + if(StringHelper.isNullOrEmptyString(bucketName)){ + bucketName=minioConfig.getBucketName(); + }else{ + minioUtils.createBucket(bucketName); + } + for (int i = 0; i uploadBast64List(String sourceTable, String sourceId, String[] sourceType, String prefix, String[] files, String bucketName) { + + + List list=new ArrayList<>(); + if(StringHelper.isNullOrEmptyString(prefix)){ + prefix=floor; + } + String day= DateUtils.getCurrentYear(); + String month=DateUtils.getCurrentMonth(); + String year=DateUtils.getCurrentYear(); + if(StringHelper.isNullOrEmptyString(bucketName)){ + bucketName=minioConfig.getBucketName(); + }else{ + minioUtils.createBucket(bucketName); + } + for (int i = 0; i getFileList(String id, String sourceId, String sourceTable, String sourceType) throws Exception { + List list=mapper.getFileList(id,sourceId,sourceType,sourceTable); + for (UploadFileVo vo:list){ + String url=minioUtils.getFileUrl(vo.getBucketName(),vo.getFilePath(),60*60*12); + vo.setLsUrl(url); + } + return list; + } + + /** + * 文件批量删除 + * @param id + * @param sourceId + * @param sourceTable + * @param sourceType + * @return + */ + public Integer delFileList(String[] id, String[] sourceId, String[] sourceTable, String[] sourceType) { + List list; + if(id!=null && id.length>0){ + list=mapper.getFileListByIds(id); + int num= mapper.delFileList(id); + if(num>0){ + remoteFile(list); + } + return num; + }else{ + int nums=0; + for (int i = 0; i < sourceId.length; i++) { + String table=null; + String type=null; + if(sourceTable!=null && sourceTable.length>0){ + table=sourceTable[i]; + } + if(sourceType!=null && sourceType.length>0){ + type=sourceType[i]; + } + list=mapper.getFileList(null,sourceId[i],table,type); + //依据资源进行删除 + int num=mapper.delFileListBySourceId(null,sourceId[i],table,type); + if(num>0){ + remoteFile(list); + } + nums+=num; + } + return nums; + } + } + + /** + * 依据id删除指定时间 + * @param id + * @param sourceId + * @param sourceTable + * @param sourceType + * @return + */ + public Integer delFileListById(String id, String sourceId, String sourceTable, String sourceType) { + List list=mapper.getFileList(id,sourceId,sourceType,sourceTable); + int num=mapper.delFileListBySourceId(id,sourceId,sourceTable,sourceType); + if(num>0){ + remoteFile(list); + } + return num; + } + + public void remoteFile( List list){ + for (UploadFileVo vo:list){ + minioUtils.removeFile(vo.getBucketName(),vo.getFilePath()); + } + + } + + + + + /** + * 判断图片base64字符串的文件格式(支持格式:BMP/PNG/JPG/JPEG/GIF/TIFF/WEBP) + * @param base64 纯净的base64编码字符串(不带data:前缀) + * @return 文件扩展名(小写),无法识别时返回null + */ + public static String getBase64Type(String base64) { + try { + // 计算所需解码长度(根据最大文件头需求) + int requiredLength = 12; // 满足WEBP的20字节需求(Base64编码后约28字符) + String encodedHeader = base64.substring(0, Math.min(base64.length(), requiredLength)); + + // 仅解码头部所需字节 + byte[] header = Base64.getDecoder().decode(encodedHeader); + + // PNG检测(需8字节) + if (header.length >= 8 && + (header[0] & 0xFF) == 0x89 && + (header[1] & 0xFF) == 0x50 && + (header[2] & 0xFF) == 0x4E && + (header[3] & 0xFF) == 0x47 && + (header[4] & 0xFF) == 0x0D && + (header[5] & 0xFF) == 0x0A && + (header[6] & 0xFF) == 0x1A && + (header[7] & 0xFF) == 0x0A) { + return "png"; + } + + // JPEG检测(前2字节) + if (header.length >= 2 && + (header[0] & 0xFF) == 0xFF && + (header[1] & 0xFF) == 0xD8) { + return "jpg"; + } + + // GIF检测(需6字节) + if (header.length >= 6 && + (header[0] & 0xFF) == 0x47 && + (header[1] & 0xFF) == 0x49 && + (header[2] & 0xFF) == 0x46 && + (header[3] & 0xFF) == 0x38 && + (header[4] & 0xFF) == 0x37 && + (header[5] & 0xFF) == 0x61) { + return "gif"; + } + + // BMP检测(前2字节) + if (header.length >= 2 && + (header[0] & 0xFF) == 0x42 && + (header[1] & 0xFF) == 0x4D) { + return "bmp"; + } + + // TIFF检测(需4字节) + if (header.length >= 4) { + int tiffMagic = ((header[0] & 0xFF) << 24) | + ((header[1] & 0xFF) << 16) | + ((header[2] & 0xFF) << 8) | + (header[3] & 0xFF); + if (tiffMagic == 0x49492A00 || tiffMagic == 0x4D4D002A) { + return "tif"; + } + } + // WebP检测(需4字节) + if (header.length >= 4 && + (header[0] & 0xFF) == 0x52 && + (header[1] & 0xFF) == 0x49 && + (header[2] & 0xFF) == 0x46 && + (header[3] & 0xFF) == 0x46) { + // 验证WebP的RIFF头 + if (header.length >= 12) { + long fileSize = ((header[4] & 0xFF) << 24) | + ((header[5] & 0xFF) << 16) | + ((header[6] & 0xFF) << 8) | + (header[7] & 0xFF); + if ((header[8] & 0xFF) == 0x57 && + (header[9] & 0xFF) == 0x45 && + (header[10] & 0xFF) == 0x42 && + (header[11] & 0xFF) == 0x50) { + return "webp"; + } + } + } + // 无法识别 + return "png"; + } catch (IllegalArgumentException e) { + return ".exe"; + } + // 无效的Base64编码 + } + + /** + * 获取文件bast64 + * @param id + * @param sourceId + * @param sourceTable + * @param sourceType + * @return + */ + public UploadFileVo getFileBast64(String id, String sourceId, String sourceTable, String sourceType) { + List list=mapper.getFileList(id,sourceId,sourceType,sourceTable); + UploadFileVo vo=list.get(0); + String bast64=minioUtils.getMinioBast64(vo.getBucketName(),vo.getFilePath()); + vo.setBast64(bast64); + return vo; + + } +} diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioUtil.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioUtil.java new file mode 100644 index 0000000..325d876 --- /dev/null +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/minio/UrkMinioUtil.java @@ -0,0 +1,480 @@ +package com.bonus.urk.minio; + + +import com.bonus.system.api.domain.SysFile; +import io.minio.*; +import io.minio.errors.MinioException; +import io.minio.http.Method; +import io.minio.messages.Item; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * MinioUtil 工具类 + * 封装 MinIO 常用操作,如文件上传、下载、删除、复制等功能 + * @author bonus + */ +@Component +public class UrkMinioUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(UrkMinioUtil.class); + + @Resource + private MinioClient minioClient; + + @Resource + private UrkMinioConfig minioConfig; + /** + * 分片大小 + */ + private static final long PART_SIZE = 5*1024*1024; + /** + * 初始化默认存储桶 + * 在 Spring 容器启动后自动调用,检查默认存储桶是否存在,若不存在则创建 + */ +// @PostConstruct + public void init() { + try { + if (bucketExists(minioConfig.getBucketName())) { + LOGGER.error("Bucket already exists: {}", minioConfig.getBucketName()); + } else { + createBucket(minioConfig.getBucketName()); + } + } catch (Exception e) { + LOGGER.error("Error initializing default bucket: {}",e.getMessage(),e); + throw new RuntimeException("Error initializing default bucket: " + e.getMessage(), e); + } + } + + /** + * 检查指定存储桶是否存在 + * @param bucketName 存储桶名称 + * @return true 表示存在,false 表示不存在 + * @throws Exception 若检查过程中发生异常 + */ + public boolean bucketExists(String bucketName) throws Exception { + return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + } + + /** + * 创建指定的存储桶 + * @param bucketName 存储桶名称 + * @throws Exception 若创建过程中发生异常 + */ + @SneakyThrows(Exception.class) + public void createBucket(String bucketName) { + if (bucketExists(bucketName)) { + LOGGER.error("Bucket already exists: {}", bucketName); + } else { + minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + LOGGER.error("Bucket created successfully: {}", bucketName); + } + } + + /** + * + * 上传文件到指定存储桶 + * @param file MultipartFile 文件对象 + * @return 上传后的文件访问 URL + * @throws Exception 若上传过程中发生异常 + */ + public SysFile uploadFile(MultipartFile file, String folderPath) throws Exception { + + if (file.getSize() < 10 * 1024 * 1024L) { + minioClient.putObject(PutObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(folderPath) + // -1 表示不限制文件大小 + .stream(file.getInputStream(), file.getInputStream().available(), -1) + .contentType(file.getContentType()) + .build()); + } else { + uploadLargeFile(folderPath, file); + } + + return SysFile.builder() + .name(file.getOriginalFilename()) + .url(folderPath).build(); + } + + /** + * 分片上传文件到指定文件夹 + * @param file MultipartFile 文件对象 + * @param folderPath 目标文件夹路径(如 "folder/subfolder") + * @throws Exception 若上传过程中发生异常 + */ + public void uploadLargeFile(String folderPath,MultipartFile file) throws Exception { + long fileSize = file.getSize(); + int partCount = (int) Math.ceil((double) fileSize / PART_SIZE); + + List partNames = new ArrayList<>(); + // 创建线程池 + ExecutorService executor = Executors.newFixedThreadPool(5); + + List> futures = new ArrayList<>(); + + // 上传每个分片 + for (int i = 0; i < partCount; i++) { + long offset = i * PART_SIZE; + long currentPartSize = Math.min(PART_SIZE, fileSize - offset); + // 设置分片名称 + String partObjectName = folderPath + "part." + i; + partNames.add(partObjectName); + + final long partOffset = offset; + final long partSizeFinal = currentPartSize; + final String partName = partObjectName; + + // 异步上传每个分片 + CompletableFuture future = CompletableFuture.runAsync(() -> { + try (InputStream inputStream = file.getInputStream()) { // 获取文件的输入流 + // 跳过文件前面的部分,直到当前分片的起始位置 + long skipped = inputStream.skip(partOffset); + if (skipped != partOffset) { + throw new RuntimeException("Could not skip to the correct part offset."); + } + + byte[] buffer = new byte[(int) partSizeFinal]; // 创建缓冲区来存储分片数据 + int bytesRead = inputStream.read(buffer); // 读取分片数据 + if (bytesRead == -1) { + throw new RuntimeException("Error reading the part data."); + } + + // 上传分片 + try (ByteArrayInputStream stream = new ByteArrayInputStream(buffer)) { + minioClient.putObject(PutObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(partName) + .stream(stream, stream.available(), -1) + .build()); + System.out.println("Uploaded part: " + partName); + } + } catch (Exception e) { + throw new RuntimeException("Error uploading part: " + partName, e); + } + }, executor); // 指定使用线程池执行任务 + + futures.add(future); // 将任务添加到 futures 列表 + } + + // 等待所有分片上传完成 + CompletableFuture allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + allOf.join(); // 阻塞等待所有任务完成 + + // 合并所有分片 + List sources = new ArrayList<>(); + for (String partName : partNames) { + sources.add(ComposeSource.builder().bucket(minioConfig.getBucketName()).object(partName).build()); + } + + // 将所有分片合并成最终文件 + try { + minioClient.composeObject(ComposeObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + // 最终文件的路径 + .object(folderPath) // 可以自定义最终文件名 + .sources(sources) + .build()); + System.out.println("Large file uploaded and composed successfully."); + } catch (MinioException e) { + throw new Exception("Error during file composition: " + e.getMessage(), e); + } + + // 删除临时分片 + for (String partName : partNames) { + minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(partName).build()); + System.out.println("Removed part: " + partName); + } + + System.out.println("Large file uploaded successfully to folder: " + folderPath); + } + + /** + * 下载指定文件,以 InputStream 形式返回 + + * @param objectName 存储对象名称(文件名) + * @return 文件的输入流 + */ + public InputStream downloadFile(String objectName){ + try (InputStream inputStream = minioClient.getObject(GetObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(objectName) + .build())) { + return inputStream; + } catch (Exception e) { + LOGGER.error("Error downloading file: {}", e.getMessage(), e); + return null; + } + + } + + + /** + * 将多个文件压缩为 ZIP 并上传至 MinIO,返回压缩文件的下载链接 + * @param bucketName 存储桶名称 + * @param objectNames 文件对象列表(文件名) + * @param zipFileName 压缩后的文件名 + * @return 压缩文件的下载 URL + * @throws Exception + */ + public String downloadFilesAsZip(String bucketName, List objectNames, String zipFileName) throws Exception { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ZipOutputStream zos = new ZipOutputStream(baos)) { + + // 压缩每个文件 + for (String objectName : objectNames) { + try (InputStream inputStream = minioClient.getObject(GetObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build())) { + + // 添加 ZipEntry + zos.putNextEntry(new ZipEntry(objectName)); + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) > 0) { + zos.write(buffer, 0, len); + } + zos.closeEntry(); + } + } + zos.finish(); + + // 上传 ZIP 文件到 MinIO + try (ByteArrayInputStream zipInputStream = new ByteArrayInputStream(baos.toByteArray())) { + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(zipFileName) + .stream(zipInputStream, zipInputStream.available(), -1) + .contentType("application/zip") + .build()); + } + } + + // 返回压缩文件的下载 URL + return getFileUrl(bucketName, zipFileName); + } + + /** + * 获取文件的临时访问 URL,指定过期时间 + * @param bucketName 存储桶名称 + * @param objectName 存储对象名称(文件名) + * @param expiryTimeInSeconds URL 的有效时长(秒) + * @return 文件的临时访问 URL + * @throws Exception 若生成 URL 过程中发生异常 + */ + @SneakyThrows(Exception.class) + public String getFileUrl(String bucketName, String objectName, int expiryTimeInSeconds) throws Exception { + return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() + .bucket(bucketName) + .object(objectName) + .expiry(expiryTimeInSeconds) + .method(Method.GET) + .build()); + } + + /** + * 获取文件bast64 + * @param bucketName + * @param path + * @return + */ + @SneakyThrows(Exception.class) + public String getMinioBast64(String bucketName,String path) { + InputStream inputStream= minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(path).build()); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + byte[] bytes = outputStream.toByteArray(); + String bast64= Base64.getEncoder().encodeToString(bytes); + inputStream.close(); + outputStream.close(); + return bast64; + } + + /** + * 删除文件 + * + * @param bucketName 存储桶 + * @param objectName 文件名称 + */ + @SneakyThrows(Exception.class) + public void removeFile(String bucketName, String objectName) { + minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build()); + } + /** + * 上传文件到指定路径 + * @param bucketName + * @param file + * @param objectName + * @return + */ + @SneakyThrows(Exception.class) + public ObjectWriteResponse uploadFile(String bucketName, MultipartFile file,String objectName) { + String contentType = file.getContentType(); + InputStream inputStream = file.getInputStream(); + ObjectWriteResponse object= minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType).stream(inputStream, inputStream.available(), -1).build()); + inputStream.close(); + return object; + } + /** + * 图片上传 + * + * @param bucketName + * @param imageBase64 + * @param + * @return + */ + public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String path) { + if (!StringUtils.isEmpty(imageBase64)) { + InputStream in = base64ToInputStream(imageBase64); + return uploadFile(bucketName, path, in); + + } + return null; + } + public static InputStream base64ToInputStream(String base64) { + ByteArrayInputStream stream = null; + try { + byte[] bytes = Base64.getEncoder().encode(base64.trim().getBytes()); + stream = new ByteArrayInputStream(bytes); + } catch (Exception e) { + e.printStackTrace(); + } + return stream; + } + + /** + * 通过流上传文件 + * + * @param bucketName 存储桶 + * @param objectName 文件对象 + * @param inputStream 文件流 + * @return + */ + @SneakyThrows(Exception.class) + public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) { + return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(), -1).build()); + } + /** + * 获取文件的临时访问 URL,默认过期时间为 7 天 + * @param bucketName 存储桶名称 + * @param objectName 存储对象名称(文件名) + * @return 文件的临时访问 URL + * @throws Exception 若生成 URL 过程中发生异常 + */ + public String getFileUrl(String bucketName, String objectName) throws Exception { + // 604800 秒 = 7 天 + return getFileUrl(bucketName, objectName, 604800); + } + + public String getFileUrl(String bucketName, String objectName,long time) throws Exception { + // 604800 秒 = 7 天 + return getFileUrl(bucketName, objectName, time); + } + + /** + * 删除指定的对象 + * @param objectName 存储对象名称(文件名) + * @throws Exception 若删除过程中发生异常 + */ + public void deleteObject( String objectName) throws Exception { + minioClient.removeObject(RemoveObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(objectName) + .build()); + } + + + /** + * 创建文件夹(通过上传带有路径的文件) + * + * @param folderPath 文件夹路径(例如 "folder1/subfolder/") + */ + public void createFolder(String folderPath) { + try { + if (!folderPath.endsWith("/")) { + folderPath += "/"; + } + // 创建一个空文件内容,模拟文件夹 + // 空文件内容 + String emptyFileContent = ""; + InputStream emptyFileStream = new ByteArrayInputStream(emptyFileContent.getBytes()); + + // 上传一个空文件到指定路径,从而模拟文件夹创建 + minioClient.putObject( + PutObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + // 使用文件夹路径 + 文件名 + .object(folderPath + "empty.txt") + .stream(emptyFileStream, 0, -1) + .contentType("application/text") + .build() + ); + } catch (Exception e) { + // 使用 LOGGER 打印异常日志 + LOGGER.error("Error occurred while fetching files from bucket: {}",minioConfig.getBucketName(), e); + } + } + + + /** + * 删除指定路径的所有对象,从而删除整个文件夹及其子文件夹。 + * + * @param folderPath 文件夹路径(例如 "folder1/subfolder/") + */ + public void deleteFolder(String folderPath) { + try { + if (!folderPath.endsWith("/")) { + folderPath += "/"; + } + // 列出指定文件夹路径下的所有对象(包括子文件夹中的对象) + Iterable> objects = minioClient.listObjects( + ListObjectsArgs.builder() + .bucket(minioConfig.getBucketName()) + .prefix(folderPath) // 设置路径前缀,列出该路径下的所有对象 + .recursive(true) // 递归列出所有子文件夹中的对象 + .build() + ); + + // 遍历所有对象并删除它们 + for (Result result : objects) { + Item item = result.get(); + String objectName = item.objectName(); + // 删除对象 + minioClient.removeObject( + RemoveObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(objectName) + .build() + ); + System.out.println("Deleted object: " + objectName); + } + System.out.println("Folder and all subfolders deleted successfully at path: " + folderPath); + } catch (Exception e) { + System.err.println("Error deleting folder and its contents at path: " + folderPath); + e.printStackTrace(); + } + } + + +} diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/ResultService.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/ResultService.java index b438fa2..70c685d 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/ResultService.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/ResultService.java @@ -1,7 +1,14 @@ package com.bonus.urk.service; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bonus.common.core.utils.StringUtils; +import com.bonus.urk.config.CommonUtils; +import com.bonus.urk.config.Constant; import com.bonus.urk.mapper.ResultMapper; import com.bonus.urk.vo.KqCmdTaskVo; +import com.bonus.urk.vo.KqDevUserIdVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; @@ -9,6 +16,9 @@ import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.concurrent.CompletableFuture; /** * 数据返回处理 业务层 @@ -49,7 +59,33 @@ public class ResultService { } } + /** + * 获取考勤机设备 + * @param taskVo + * @param req + * @param resp + */ public void insertUserIdList(KqCmdTaskVo taskVo, HttpServletRequest req, HttpServletResponse resp) { + try { + // 解析request输入流 + String jsonStr = getRequestBody(req); + log.debug("人员列表信息:{}", jsonStr); + if(StringUtils.isNotBlank(jsonStr)) { + //数据处理 + JSONObject json=JSON.parseObject(jsonStr); + JSONArray aray=json.getJSONArray("usersId"); + List list=JSON.parseArray(aray.toJSONString(), KqDevUserIdVo.class); + mapper.insertKqDevUserList2(list,taskVo.getDeviceCode()); + } + resp.addHeader(Constant.DEVICE_HEADER_RESPONSE_CODE, Constant.OK); + resp.addHeader(Constant.DEVICE_HEADER_TRANS_ID, taskVo.getId()); + resp.getWriter().write(""); + } catch (Exception e) { + log.error(e.toString(),e); + } + + + } public void insertLogData(KqCmdTaskVo taskVo, HttpServletRequest req, HttpServletResponse resp) { @@ -64,7 +100,17 @@ public class ResultService { public void insertUserInfo(KqCmdTaskVo taskVo, HttpServletRequest req, HttpServletResponse resp) { } + /** + * 删除考勤人员回调 + * @param taskVo + * @param req + * @param resp + */ public void insertDeleteUser(KqCmdTaskVo taskVo, HttpServletRequest req, HttpServletResponse resp) { + + List userIds=mapper.getTaskUser(taskVo.getId()); + mapper.delKqDevUser(userIds,taskVo.getDeviceCode()); + } /** @@ -77,7 +123,9 @@ public class ResultService { try{ //跟新任务状态 mapper.updateUserIssuedStatus(taskVo,1); - + //将人员数据同步到考勤人员里面去 + List userIds=mapper.getTaskUser(taskVo.getId()); + mapper.insertKqDevUserList(userIds,taskVo.getDeviceCode()); }catch (Exception e){ log.error(e.toString(),e); } @@ -87,9 +135,24 @@ public class ResultService { try{ //跟新任务状态 mapper.delCmdTaskId(taskVo); - mapper.updateTaskHisById(taskVo); + int num= mapper.updateTaskHisById(taskVo); + System.err.println(num); }catch (Exception e){ log.error(e.toString(),e); } } + + + private String getRequestBody(HttpServletRequest req) { + String key = CommonUtils.getRequestBodyKey(req); + + byte[] requestData = CommonUtils.GetRequestStreamBytes(req); + String jsonStr = null; + try { + jsonStr = new String(requestData, Constant.CHART_SET); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return jsonStr; + } } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/SendUserService.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/SendUserService.java index cbf0a4d..b95cd7a 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/SendUserService.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/SendUserService.java @@ -8,6 +8,7 @@ import com.bonus.urk.config.TaskStatusEnum; import com.bonus.urk.mapper.SendUserMapper; import com.bonus.urk.vo.DeviceVo; import com.bonus.urk.vo.KqCmdTaskVo; +import com.bonus.urk.vo.KqDevUserIdVo; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import lombok.extern.slf4j.Slf4j; @@ -184,5 +185,52 @@ public class SendUserService { } } + /** + * 考勤机解绑工程 + * @param deviceCode + * @param proId + */ + public void delDevByProId(String deviceCode, int proId) { + try{ + String createTime= DateUtils.getTime(); + KqCmdTaskVo taskVo=new KqCmdTaskVo(); + taskVo.setDeviceCode(deviceCode); + taskVo.setProId(String.valueOf(proId)); + taskVo.setCreateTime(createTime); + taskVo.setCmdCode("DELETE_USER"); + //等待执行 + taskVo.setTransStatus(TaskStatusEnum.WAIT.ordinal()); + //分页查询 + delDevUserList(deviceCode,1,taskVo); + }catch (Exception e){ + log.error(e.toString()); + } + } + public void delDevUserList(String deviceCode,int pageNum,KqCmdTaskVo taskVo){ + //要获取考勤机当前的全部用户数据 + PageHelper.startPage(pageNum, PAGE_SIZE); + List list=mapper.getDevUserId(deviceCode); + PageInfo pageInfo =new PageInfo(list); + //分页查询+ + if (!list.isEmpty()){ + String json= JSON.toJSONString(list); + taskVo.setCmdParam(json); + //添加任务 + mapper.insertCmdTask(taskVo); + //添加历史记录 + mapper.insertCmdTaskHistory(taskVo); + //添加人员 + mapper.insertCmdTaskUser(list,taskVo); + int pageSize=pageInfo.getPageNum(); + int pageTotal=pageInfo.getPages(); + if(pageSize res=fileService.getFileBast64(null,sourceId,sourceTable,sourceTyp, SecurityConstants.INNER); - if(res.getCode()==R.SUCCESS){ - UploadFileVo vo=res.getData(); - return vo.getBast64(); + UploadFileVo uploadFileVo=fileService.getFileBast64(null,sourceId,sourceTable,sourceTyp); + if(uploadFileVo!=null){ + return uploadFileVo.getBast64(); } return null; } @@ -487,4 +484,15 @@ public class TaskService { } + public void updateById(DeviceTaskVo task) { + try{ + mapper.updateById(task); + }catch (Exception e){ + log.error(e.toString(),e); + } + } + + public List selectCmdTaskList(String devCode) { + return mapper.selectCmdTaskList(devCode); + } } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/UserFaceHandleService.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/UserFaceHandleService.java index 12f46e8..27f1a89 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/UserFaceHandleService.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/service/UserFaceHandleService.java @@ -6,8 +6,10 @@ import com.bonus.common.core.domain.R; import com.bonus.common.core.utils.DateUtils; import com.bonus.common.core.utils.StringUtils; import com.bonus.system.api.RemoteUploadUtilsService; +import com.bonus.system.api.domain.FileVo; import com.bonus.system.api.model.UploadFileVo; import com.bonus.urk.mapper.UserFaceHandleMapper; +import com.bonus.urk.minio.UrkMinioService; import com.bonus.urk.vo.BmWorkerEinUserVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -29,7 +31,7 @@ public class UserFaceHandleService { private UserFaceHandleMapper mapper; @Resource - private RemoteUploadUtilsService fileService; + private UrkMinioService fileService; /** * 依据用户id 查询施工工程信息 @@ -63,17 +65,14 @@ public class UserFaceHandleService { Integer num=mapper.getTodayIsExit(vo); //每日新增一条考勤信息 if(num==null || num ==0){ - R res=fileService.uploadBast64(vo.getAttPhoto(),"bm_att_person",vo.getId(),"1", "attr",null,SecurityConstants.INNER); - if(res.getCode()==R.SUCCESS){ - UploadFileVo uploadFileVo=res.getData(); + UploadFileVo uploadFileVo=fileService.upload("bm_att_person",vo.getId(),"考勤照片","attr",vo.getAttPhoto(),null); + if(uploadFileVo!=null){ vo.setImage(uploadFileVo.getPath()); mapper.insertAttPerson(vo); } } - //新增考勤记录 - R res=fileService.uploadBast64(vo.getAttPhoto(),"bm_att_record",vo.getId(),"1", "attr",null,SecurityConstants.INNER); - if(res.getCode()==R.SUCCESS){ - UploadFileVo uploadFileVo=res.getData(); + UploadFileVo uploadFileVo=fileService.upload("bm_att_record",vo.getId(),"考勤照片","attr",vo.getAttPhoto(),null); + if(uploadFileVo!=null){ vo.setImage(uploadFileVo.getPath()); mapper.insertAttRecord(vo); } @@ -82,4 +81,28 @@ public class UserFaceHandleService { } } + + + + public void addWrcUser(BmWorkerEinUserVo vo) { + try{ + String id=StringUtils.randomUUID(); + vo.setId(id); + vo.setAttMonth(DateUtils.getCurrentMonth()); + vo.setAttDay(DateUtils.getDate()); + vo.setCreateTime(DateUtils.getTime()); + Integer num=mapper.getTodayNoRootIsExit(vo); + //每日新增一条考勤信息 + if(num==null || num ==0){ + UploadFileVo uploadFileVo=fileService.upload("bm_att_record_no_ru",vo.getId(),"考勤照片","noattr",vo.getAttPhoto(),null); + if(uploadFileVo!=null){ + vo.setImage(uploadFileVo.getPath()); + mapper.addWrcUser(vo); + } + } + }catch (Exception e){ + log.error(e.toString(),e); + } + + } } diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/servlet/DeviceServlet.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/servlet/DeviceServlet.java index 1c4e290..2169a0a 100644 --- a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/servlet/DeviceServlet.java +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/servlet/DeviceServlet.java @@ -1,27 +1,20 @@ package com.bonus.urk.servlet; import cn.hutool.core.codec.Base64; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.io.FileUtil; -import cn.hutool.core.util.NumberUtil; - import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.bonus.urk.config.CacheConstant; +import com.bonus.common.redis.service.RedisService; import com.bonus.urk.config.Constant; import com.bonus.urk.config.DeviceUserDto; -import com.bonus.urk.config.RedisUtils; import com.bonus.urk.handle.DeviceHandle; import com.bonus.urk.handle.ReceiveCmd; import com.bonus.urk.handle.ResultHandle; import com.bonus.urk.handle.UserFaceHandle; -import com.bonus.urk.service.TaskService; import com.bonus.urk.vo.DeviceVo; import lombok.extern.slf4j.Slf4j; import org.hibernate.validator.internal.util.StringHelper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.ZSetOperations; -import org.springframework.data.redis.core.ZSetOperations; import org.springframework.web.context.support.SpringBeanAutowiringSupport; import javax.servlet.ServletConfig; @@ -31,13 +24,9 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; -import java.sql.Timestamp; import java.util.ArrayList; -import java.util.Calendar; import java.util.List; - -import static com.bonus.urk.config.InstructEnum.RESET_FK; -import static com.bonus.urk.config.InstructEnum.SET_USER_INFO; +import java.util.concurrent.TimeUnit; /** * servlet - 设备数据监听 @@ -57,14 +46,11 @@ public class DeviceServlet extends HttpServlet { @Autowired private UserFaceHandle userFaceHandle; - @Autowired - private TaskService taskService; - @Autowired private ResultHandle resultHandle; @Autowired - private RedisUtils redisUtils; + private RedisService redisUtils; /** @@ -86,7 +72,7 @@ public class DeviceServlet extends HttpServlet { resp.addHeader(Constant.DEVICE_HEADER_RESPONSE_CODE, Constant.ERROR_NO_CMD); return; } - redisUtils.set("att_dev:status",1,600); + redisUtils.setCacheObject("att_dev:status",1,600L, TimeUnit.SECONDS); String asTransId = req.getHeader(Constant.DEVICE_HEADER_TRANS_ID); String requestCode = req.getHeader(Constant.DEVICE_HEADER_REQUEST_CODE); // zSetOperations.add(CacheConstant.DEVICE_ONLINE_SET_CACHE, deviceVo.getDevCode(), System.currentTimeMillis()); diff --git a/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/vo/KqDevUserIdVo.java b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/vo/KqDevUserIdVo.java new file mode 100644 index 0000000..c766ff5 --- /dev/null +++ b/bonus-modules/bonus-urk/src/main/java/com/bonus/urk/vo/KqDevUserIdVo.java @@ -0,0 +1,23 @@ +package com.bonus.urk.vo; + +import lombok.Data; + +/** + * @author 黑子 + */ +@Data +public class KqDevUserIdVo { + /** + * 主键 + */ + private String name; + /** + * 用户id + */ + private String userId; + /** + * 设备编码 + */ + private String devCode; + +} diff --git a/bonus-modules/bonus-urk/src/main/resources/bootstrap-local.yml b/bonus-modules/bonus-urk/src/main/resources/bootstrap-local.yml index 1bc9bed..c7c02b8 100644 --- a/bonus-modules/bonus-urk/src/main/resources/bootstrap-local.yml +++ b/bonus-modules/bonus-urk/src/main/resources/bootstrap-local.yml @@ -6,15 +6,15 @@ spring: cloud: nacos: username: nacos - password: Jjsp@nacos2023 + password: nacos discovery: # 服务注册地址 - server-addr: 127.0.0.1:18848 - namespace: rela_name_system + server-addr: 192.168.0.14:8848 + namespace: fangliang_test config: # 配置中心地址 - server-addr: 127.0.0.1:18848 - namespace: rela_name_system + server-addr: 192.168.0.14:8848 + namespace: fangliang_test # 配置文件格式 file-extension: yml # 共享配置 diff --git a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/ResultMapper.xml b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/ResultMapper.xml index 66c56f7..edc9a6e 100644 --- a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/ResultMapper.xml +++ b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/ResultMapper.xml @@ -3,6 +3,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + + replace into kq_dev_user_id( + dev_code, + user_id + )values + + (#{deviceCode},#{item}) + + + + + replace into kq_dev_user_id( + dev_code, + user_id, + user_name + )values + + (#{deviceCode},#{item.userId},#{item.name}) + + + update kq_cmd_task set trans_status_update_time=#{updateTime},trans_status=#{transStatus} where id=#{id} @@ -15,15 +36,27 @@ update pm_worker_user_issued set result=#{result} where task_id=#{taskVo.id} - delete from kq_cmd_task where id=#{id} + + delete from kq_dev_user_id + where dev_code=#{deviceCode} and + user_id in + + #{userId} + + + diff --git a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/SendUserMapper.xml b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/SendUserMapper.xml index a45e9cc..97bb4d6 100644 --- a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/SendUserMapper.xml +++ b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/SendUserMapper.xml @@ -100,5 +100,11 @@ left join pm_project pro on pro.id=bwem.pro_id where pro.is_shanghai=1 + + diff --git a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UrkMinioMapper.xml b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UrkMinioMapper.xml new file mode 100644 index 0000000..38c90a9 --- /dev/null +++ b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UrkMinioMapper.xml @@ -0,0 +1,79 @@ + + + + + + + insert into bm_files( + source_table, source_id, source_type, file_name, file_key,bucket_name, create_time, update_time, is_active, origin_file_name,file_url,file_path + )values (#{sourceTable},#{sourceId},#{sourceType},#{fileName},#{filePath},#{bucketName},now(),now(),1,#{originFileName},#{url},#{path}) + + + + insert into bm_files ( source_table, source_id, source_type, file_name, file_key,bucket_name, create_time, update_time, is_active, origin_file_name,file_url,file_path + ) values + + (#{item.sourceTable},#{item.sourceId},#{item.sourceType},#{item.fileName},#{item.filePath}, + #{item.bucketName},now(),now(),1,#{item.originFileName},#{item.url},#{item.path}) + + + + + update bm_files set is_active=0 + where id in + + #{item} + + + + + update bm_files set is_active = 0 + + + and source_id=#{sourceId} + + + and source_type= #{sourceType} + + + and source_table= #{sourceTable} + + + and id= #{id} + + + + + + + + diff --git a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UserFaceHandleMapper.xml b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UserFaceHandleMapper.xml index 7f2e80a..ee8da83 100644 --- a/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UserFaceHandleMapper.xml +++ b/bonus-modules/bonus-urk/src/main/resources/mapper/urk/UserFaceHandleMapper.xml @@ -9,7 +9,7 @@ id, worker_id, device_code,dev_name, id_number, name, pro_id, pro_name, sub_id, sub_name, team_id, team_name,org_id, org_name, att_month, att_day, daily_wage, att_time, att_photo, is_repair, create_time, is_active,contract_id )values (#{id},#{userId},#{devCode},#{devName},#{idNumber},#{userName},#{proId},#{proName},#{subId},#{subName},#{teamId},#{teamName},#{orgId},#{orgName}, - #{attMonth},#{attDay,#{dailyWage},#{attTime},#{image},#{isRepair},#{createTime},1,#{contractId} + #{attMonth},#{attDay},#{dailyWage},#{attTime},#{image},#{isRepair},#{createTime},1,#{contractId} ) @@ -19,7 +19,7 @@ id, worker_id, device_code, id_number, dev_name,name, pro_id, pro_name, sub_id, sub_name, team_id, team_name,org_id, org_name, att_month, att_day, daily_wage, att_time, att_photo, is_repair, create_time, is_active,contract_id )values (#{id},#{userId},#{devCode},#{idNumber},#{devName},#{userName},#{proId},#{proName},#{subId},#{subName},#{teamId},#{teamName},#{orgId},#{orgName}, - #{attMonth},#{attDay,#{dailyWage},#{attTime},#{image},#{isRepair},#{createTime},1,#{contractId} + #{attMonth},#{attDay},#{dailyWage},#{attTime},#{image},#{isRepair},#{createTime},1,#{contractId} ) @@ -37,4 +37,19 @@ from bm_att_person where worker_id=#{userId} and is_active=1 and att_day=#{attDay} + + + + insert into bm_att_record_no_ru( + id, worker_id, device_code,dev_name, id_number, name, pro_id, pro_name, sub_id, sub_name, team_id, team_name,org_id, org_name, + att_month, att_day, daily_wage, att_time, att_photo, is_repair, create_time, is_active,contract_id + )values (#{id},#{userId},#{devCode},#{devName},#{idNumber},#{userName},#{proId},#{proName},#{subId},#{subName},#{teamId},#{teamName},#{orgId},#{orgName}, + #{attMonth},#{attDay},#{dailyWage},#{attTime},#{image},#{isRepair},#{createTime},1,#{contractId} + ) + +