diff --git a/db/1000pjcloudx_thirdparty.sql b/db/1000pjcloudx_thirdparty.sql index 0561eec61..c5e42e9eb 100644 --- a/db/1000pjcloudx_thirdparty.sql +++ b/db/1000pjcloudx_thirdparty.sql @@ -1,4 +1,5 @@ -create database `pjcloudx_thirdparty` default character set utf8mb4 collate utf8mb4_general_ci; +create +database `pjcloudx_thirdparty` default character set utf8mb4 collate utf8mb4_general_ci; -- ---------------------------- -- Table structure for third_zy_log @@ -133,4 +134,4 @@ CREATE TABLE `third_zy_id_dict` ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci - ROW_FORMAT = DYNAMIC COMMENT ='正元字典id对应 id + bizType 唯一'; \ No newline at end of file + ROW_FORMAT = DYNAMIC COMMENT ='正元字典id对应 id + bizType 唯一'; diff --git a/db/1002pjcloudx_integrated.sql b/db/1002pjcloudx_integrated.sql index 632a599de..b99057c46 100644 --- a/db/1002pjcloudx_integrated.sql +++ b/db/1002pjcloudx_integrated.sql @@ -13,3 +13,35 @@ CREATE TABLE `hard_panel_setting` ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='大屏配置表'; +-- ---------------------------- +-- Table structure for ad_record +-- ---------------------------- +DROP TABLE IF EXISTS `ad_record`; +CREATE TABLE `ad_record` +( + `id` bigint NOT NULL COMMENT '主键', + `user_id` bigint NOT NULL COMMENT '观看广告用户id', + `trans_id` varchar(32) DEFAULT NULL COMMENT '交易id', + `ad_id` varchar(32) DEFAULT NULL COMMENT '广告id', + `ad_type` varchar(64) DEFAULT NULL COMMENT '广告类型', + `ad_provider` varchar(128) DEFAULT NULL COMMENT '广告服务商', + `visit_platform` varchar(128) DEFAULT NULL COMMENT '观看手机平台', + `visit_start_time` datetime DEFAULT NULL COMMENT '观看开始时间', + `visit_end_time` datetime DEFAULT NULL COMMENT '观看结束时间', + `visit_duration` int DEFAULT NULL COMMENT '观看时长(秒)', + `status` varchar(32) DEFAULT NULL COMMENT '观看状态', + `extra` text DEFAULT NULL COMMENT '额外参数', + + `ad_predict_price` int DEFAULT NULL COMMENT '广告预计收入(单位:分)', + + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `update_by` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '删除时间', + `tenant_id` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_general_ci + ROW_FORMAT = DYNAMIC COMMENT ='广告记录'; \ No newline at end of file diff --git a/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/ServiceNameConstants.java b/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/ServiceNameConstants.java index fe01e2747..e5c4a1a3a 100644 --- a/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/ServiceNameConstants.java +++ b/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/ServiceNameConstants.java @@ -25,70 +25,75 @@ package com.bsd.pjcloud.common.core.constant; */ public interface ServiceNameConstants { - /** - * 认证中心 - */ - String AUTH_SERVICE = "pjcloud-auth"; + /** + * 认证中心 + */ + String AUTH_SERVICE = "pjcloud-auth"; - /** - * UMPS模块 - */ - String UPMS_SERVICE = "pjcloud-upms-biz"; + /** + * UMPS模块 + */ + String UPMS_SERVICE = "pjcloud-upms-biz"; - /** - * app服务 - */ - String APP_SERVER = "pjcloud-app-server-biz"; + /** + * app服务 + */ + String APP_SERVER = "pjcloud-app-server-biz"; - /** - * 流程引擎 - */ - String FLOW_ENGINE_SERVER = "pjcloud-flow-engine-biz"; + /** + * 流程引擎 + */ + String FLOW_ENGINE_SERVER = "pjcloud-flow-engine-biz"; - /** - * 流程工单 - */ - String FLOW_TASK_SERVER = "pjcloud-flow-task-biz"; + /** + * 流程工单 + */ + String FLOW_TASK_SERVER = "pjcloud-flow-task-biz"; - /** - * 代码生成模块 - */ - String CODEGEN_SERVICE = "pjcloud-codegen"; + /** + * 代码生成模块 + */ + String CODEGEN_SERVICE = "pjcloud-codegen"; - /** - * 第三方服务 - */ - String THIRDPARTY_SERVICE = "pjcloud-thirdparty-biz"; + /** + * 第三方服务 + */ + String THIRDPARTY_SERVICE = "pjcloud-thirdparty-biz"; - /** - * 智慧食堂服务 - */ - String CANTEEN_SERVICE = "pjcloud-canteen-biz"; + /** + * 智慧食堂服务 + */ + String CANTEEN_SERVICE = "pjcloud-canteen-biz"; - /** - * 超市服务 - */ - String SUPERMARKET_SERVICE = "pjcloud-supermarket-biz"; + /** + * 超市服务 + */ + String SUPERMARKET_SERVICE = "pjcloud-supermarket-biz"; - /** - * 超市erp服务 - */ - String SUPERMARKET_ERP_SERVICE = "pjcloud-supermarket-erp-biz"; + /** + * 超市erp服务 + */ + String SUPERMARKET_ERP_SERVICE = "pjcloud-supermarket-erp-biz"; - /** - * 钱包模块 - */ - String WALLET_SERVICE = "pjcloud-wallet-biz"; + /** + * 钱包模块 + */ + String WALLET_SERVICE = "pjcloud-wallet-biz"; - /** - * 硬件模块 - */ - String HARDWARE_SERVICE = "pjcloud-hardware-biz"; + /** + * 硬件模块 + */ + String HARDWARE_SERVICE = "pjcloud-hardware-biz"; - /** - * mqtt模块 - */ - String MQTT_SERVICE = "pjcloud-mqtt-biz"; + /** + * mqtt模块 + */ + String MQTT_SERVICE = "pjcloud-mqtt-biz"; + + /** + * 综合服务 + */ + String INTEGRATED_SERVICE = "pjcloud-integrated-biz"; } diff --git a/pjcloud-integrated/pjcloud-integrated-api/pom.xml b/pjcloud-integrated/pjcloud-integrated-api/pom.xml index c35aa605f..9595afc27 100644 --- a/pjcloud-integrated/pjcloud-integrated-api/pom.xml +++ b/pjcloud-integrated/pjcloud-integrated-api/pom.xml @@ -42,5 +42,11 @@ com.bsd pjcloud-common-excel - + + com.bsd + pjcloud-thirdparty-api + 5.7.0 + compile + + diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/api/feign/RemoterIntegratedAdService.java b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/api/feign/RemoterIntegratedAdService.java new file mode 100644 index 000000000..4a516bda8 --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/api/feign/RemoterIntegratedAdService.java @@ -0,0 +1,18 @@ +package com.bsd.pjcloud.integrated.api.feign; + +import com.bsd.pjcloud.common.core.constant.ServiceNameConstants; +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.feign.annotation.NoToken; +import com.bsd.pjcloud.thirdparty.dto.ad.UniappAdCallbackDto; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(contextId = "RemoterIntegratedAdService", value = ServiceNameConstants.INTEGRATED_SERVICE) +public interface RemoterIntegratedAdService { + + @NoToken + @PostMapping("/ad-record/uniapp-ad-callback") + R uniappAdCallback(@RequestBody UniappAdCallbackDto body); + +} diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/constant/ad/AdRecordStatus.java b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/constant/ad/AdRecordStatus.java new file mode 100644 index 000000000..e2c47ee9b --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/constant/ad/AdRecordStatus.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.integrated.constant.ad; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum AdRecordStatus { + + SUCCESS("100", "观看成功"), + ; + + private final String type; + private final String description; + +} diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/constant/ad/AdTypeEnum.java b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/constant/ad/AdTypeEnum.java new file mode 100644 index 000000000..745258fc9 --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/java/com/bsd/pjcloud/integrated/constant/ad/AdTypeEnum.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.integrated.constant.ad; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum AdTypeEnum { + + UNIAPP_INFORMATION_STREAM("90", "uniapp-信息流广告"), + UNIAPP_REWARDED("100", "uniapp-激励广告"), + ; + + private final String type; + private final String description; + +} diff --git a/pjcloud-integrated/pjcloud-integrated-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports b/pjcloud-integrated/pjcloud-integrated-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports new file mode 100644 index 000000000..899644c99 --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports @@ -0,0 +1 @@ +com.bsd.pjcloud.integrated.api.feign.RemoterIntegratedAdService \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/controller/ad/AdRecordController.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/controller/ad/AdRecordController.java new file mode 100755 index 000000000..e18bbf422 --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/controller/ad/AdRecordController.java @@ -0,0 +1,125 @@ +package com.bsd.pjcloud.integrated.controller.ad; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.log.annotation.SysLog; +import com.bsd.pjcloud.common.security.annotation.Inner; +import com.bsd.pjcloud.common.security.service.PjcloudUser; +import com.bsd.pjcloud.common.security.util.SecurityUtils; +import com.bsd.pjcloud.integrated.dto.ad.AdRecordDto; +import com.bsd.pjcloud.integrated.service.AdRecordService; +import com.bsd.pjcloud.integrated.vo.ad.AdRecordVo; +import com.bsd.pjcloud.integrated.entity.ad.AdRecordEntity; +import com.bsd.pjcloud.thirdparty.dto.ad.UniappAdCallbackDto; +import org.springframework.security.access.prepost.PreAuthorize; +import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.HttpHeaders; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 广告记录 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/ad-record") +@Tag(description = "ad-record", name = "广告记录") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class AdRecordController { + + private final AdRecordService adRecordService; + + /* ************************************* start 远程调用 start ************************************* */ + + @Operation(summary = "uniapp广告回调", description = "uniapp广告回调") + @Inner + @PostMapping("/uniapp-ad-callback") + public R uniappAdCallback(@RequestBody UniappAdCallbackDto body) { + return R.ok(adRecordService.uniappAdCallback(body)); + } + + /* ************************************* start 远程调用 start ************************************* */ + + /* ************************************* start 增加广告浏览记录 start ************************************* */ + @Operation(summary = "上报广告浏览记录", description = "上报广告浏览记录") + @Inner + @PostMapping("/app/report-ad-view") + public R reportAdView(@RequestBody AdRecordDto dto) { + PjcloudUser user = SecurityUtils.getUser(); + dto.setUserId(user.getId()); + return R.ok(adRecordService.reportAdView(dto)); + } + /* ************************************* start 增加广告浏览记录 start ************************************* */ + + /** + * 分页查询 + */ + @Operation(summary = "分页查询", description = "分页查询") + @GetMapping("/page") + @PreAuthorize("@pms.hasPermission('third_thirdAdRecord_view')") + public R> getThirdAdRecordPage(@ParameterObject Page page, @ParameterObject AdRecordDto dto) { + return R.ok(adRecordService.pageList(page, dto)); + } + + /** + * 通过id查询广告记录 + */ + @Operation(summary = "通过id查询", description = "通过id查询") + @GetMapping("/{id}") + @PreAuthorize("@pms.hasPermission('third_thirdAdRecord_view')") + public R getById(@PathVariable("id") Long id) { + return R.ok(adRecordService.getById(id)); + } + + /** + * 新增广告记录 + */ + @Operation(summary = "新增广告记录", description = "新增广告记录") + @SysLog("新增广告记录") + @PostMapping + @PreAuthorize("@pms.hasPermission('third_thirdAdRecord_add')") + public R save(@RequestBody AdRecordEntity thirdAdRecord) { + return R.ok(adRecordService.save(thirdAdRecord)); + } + + /** + * 修改广告记录 + */ + @Operation(summary = "修改广告记录", description = "修改广告记录") + @SysLog("修改广告记录") + @PutMapping + @PreAuthorize("@pms.hasPermission('third_thirdAdRecord_edit')") + public R updateById(@RequestBody AdRecordEntity thirdAdRecord) { + return R.ok(adRecordService.updateById(thirdAdRecord)); + } + + /** + * 通过id删除广告记录 + */ + @Operation(summary = "通过id删除广告记录", description = "通过id删除广告记录") + @SysLog("通过id删除广告记录") + @DeleteMapping + @PreAuthorize("@pms.hasPermission('third_thirdAdRecord_del')") + public R removeById(@RequestBody Long[] ids) { + return R.ok(adRecordService.removeBatchByIds(CollUtil.toList(ids))); + } + + /** + * 导出excel 表格 + */ + @ResponseExcel + @GetMapping("/export") + @PreAuthorize("@pms.hasPermission('third_thirdAdRecord_export')") + public List export(AdRecordEntity thirdAdRecord, Long[] ids) { + return adRecordService.list(Wrappers.lambdaQuery(thirdAdRecord).in(ArrayUtil.isNotEmpty(ids), AdRecordEntity::getId, ids)); + } +} \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/dto/ad/AdRecordDto.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/dto/ad/AdRecordDto.java new file mode 100644 index 000000000..3a2990a2f --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/dto/ad/AdRecordDto.java @@ -0,0 +1,13 @@ +package com.bsd.pjcloud.integrated.dto.ad; + +import com.bsd.pjcloud.integrated.entity.ad.AdRecordEntity; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class AdRecordDto extends AdRecordEntity { + + private LocalDateTime[] createTimeList; + +} diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/entity/ad/AdRecordEntity.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/entity/ad/AdRecordEntity.java new file mode 100755 index 000000000..5618d8ed6 --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/entity/ad/AdRecordEntity.java @@ -0,0 +1,143 @@ +package com.bsd.pjcloud.integrated.entity.ad; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import com.bsd.pjcloud.common.core.util.TenantTable; + +import java.time.LocalDateTime; + +/** + * 广告记录 + */ +@Data +@TenantTable +@TableName("ad_record") +@EqualsAndHashCode(callSuper = true) +@Schema(description = "广告记录") +public class AdRecordEntity extends Model { + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private Long id; + + /** + * 观看广告用户id + */ + @Schema(description = "观看广告用户id") + private Long userId; + + /** + * 交易id + */ + @Schema(description = "交易id") + private String transId; + + /** + * 广告id + */ + @Schema(description = "广告id") + private String adId; + + /** + * 广告类型 + */ + @Schema(description = "广告类型") + private String adType; + + /** + * 广告服务商 + */ + @Schema(description = "广告服务商") + private String adProvider; + + /** + * 观看手机平台 + */ + @Schema(description = "观看手机平台") + private String visitPlatform; + + /** + * 观看开始时间 + */ + @Schema(description = "观看开始时间") + private LocalDateTime visitStartTime; + + /** + * 观看结束时间 + */ + @Schema(description = "观看结束时间") + private LocalDateTime visitEndTime; + + /** + * 观看时长(秒) + */ + @Schema(description = "观看时长(秒)") + private Integer visitDuration; + + /** + * 观看状态 + */ + @Schema(description = "观看状态") + private String status; + + /** + * 额外参数 + */ + @Schema(description = "额外参数") + private String extra; + + + /** + * 广告预计收入 + */ + @Schema(description = "广告预计收入") + private Integer adPredictPrice; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "创建人") + private String createBy; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "创建时间") + private LocalDateTime createTime; + + /** + * 更新人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @Schema(description = "更新人") + private String updateBy; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + /** + * 删除时间 + */ + @TableLogic + @TableField(fill = FieldFill.INSERT) + @Schema(description = "删除时间") + private String delFlag; + + /** + * tenantId + */ + @Schema(description = "tenantId") + private Long tenantId; +} \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/mapper/ad/ThirdAdRecordMapper.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/mapper/ad/ThirdAdRecordMapper.java new file mode 100755 index 000000000..28781cb1a --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/mapper/ad/ThirdAdRecordMapper.java @@ -0,0 +1,16 @@ +package com.bsd.pjcloud.integrated.mapper.ad; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper; +import com.bsd.pjcloud.integrated.dto.ad.AdRecordDto; +import com.bsd.pjcloud.integrated.entity.ad.AdRecordEntity; +import com.bsd.pjcloud.integrated.vo.ad.AdRecordVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface ThirdAdRecordMapper extends PjcloudBaseMapper { + + Page selectPage(Page page, @Param("dto") AdRecordDto dto); + +} \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/AdRecordService.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/AdRecordService.java new file mode 100755 index 000000000..b5ceda5fc --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/AdRecordService.java @@ -0,0 +1,23 @@ +package com.bsd.pjcloud.integrated.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.bsd.pjcloud.integrated.dto.ad.AdRecordDto; +import com.bsd.pjcloud.integrated.vo.ad.AdRecordVo; +import com.bsd.pjcloud.integrated.entity.ad.AdRecordEntity; +import com.bsd.pjcloud.thirdparty.dto.ad.UniappAdCallbackDto; + +public interface AdRecordService extends IService { + + /** + * uniapp广告回调 + */ + Boolean uniappAdCallback(UniappAdCallbackDto body); + + /** + * 上报广告浏览记录 + */ + Boolean reportAdView(AdRecordDto dto); + + Page pageList(Page page, AdRecordDto dto); +} \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/ad/AdRecordServiceImpl.java b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/ad/AdRecordServiceImpl.java new file mode 100755 index 000000000..af9071794 --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/java/com/bsd/pjcloud/integrated/service/impl/ad/AdRecordServiceImpl.java @@ -0,0 +1,102 @@ +package com.bsd.pjcloud.integrated.service.impl.ad; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bsd.pjcloud.admin.api.feign.RemoteUserService; +import com.bsd.pjcloud.admin.api.utils.DataUtil; +import com.bsd.pjcloud.admin.api.vo.UserVO; +import com.bsd.pjcloud.common.core.util.BeanUtils; +import com.bsd.pjcloud.common.core.util.CollectionUtils; +import com.bsd.pjcloud.integrated.constant.ad.AdRecordStatus; +import com.bsd.pjcloud.integrated.constant.ad.AdTypeEnum; +import com.bsd.pjcloud.integrated.dto.ad.AdRecordDto; +import com.bsd.pjcloud.integrated.mapper.ad.ThirdAdRecordMapper; +import com.bsd.pjcloud.integrated.service.AdRecordService; +import com.bsd.pjcloud.integrated.vo.ad.AdRecordVo; +import com.bsd.pjcloud.integrated.entity.ad.AdRecordEntity; +import com.bsd.pjcloud.thirdparty.dto.ad.UniappAdCallbackDto; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 广告记录 + */ +@Service +@Slf4j +@AllArgsConstructor +public class AdRecordServiceImpl extends ServiceImpl implements AdRecordService { + + private final RemoteUserService remoteUserService; + + /** + * uniapp广告回调 + */ + @Override + @Transactional + public Boolean uniappAdCallback(UniappAdCallbackDto body) { + AdTypeEnum adType = AdTypeEnum.UNIAPP_REWARDED; + // 是否重复 + AdRecordEntity detail = getByTransId(adType, body.getTransId()); + if (ObjectUtil.isNotEmpty(detail)) { + log.error("uniapp广告回调,transId对应的数据已经存在,json:{}", JSONUtil.toJsonStr(detail)); + return false; + } + AdRecordEntity dto = new AdRecordEntity(); + dto.setUserId(body.getUserId()); + dto.setTransId(body.getTransId()); + dto.setAdId(body.getAdpid()); + dto.setAdType(adType.getType()); + dto.setAdProvider(body.getProvider()); + dto.setVisitPlatform(body.getPlatform()); + dto.setExtra(body.getExtra()); + dto.setStatus(AdRecordStatus.SUCCESS.getType()); + dto.setAdPredictPrice(0); + baseMapper.insert(dto); + return true; + } + + /** + * 上报广告浏览记录 + */ + @Override + public Boolean reportAdView(AdRecordDto dto) { + AdRecordEntity saveObj = BeanUtils.toBean(dto, AdRecordEntity.class); + saveObj.setStatus(AdRecordStatus.SUCCESS.getType()); + saveObj.setAdPredictPrice(0); + baseMapper.insert(dto); + return true; + } + + public AdRecordEntity getByTransId(AdTypeEnum adType, String transId) { + return baseMapper.selectOne(new LambdaQueryWrapper() + .eq(AdRecordEntity::getAdType, adType.getType()) + .eq(AdRecordEntity::getTransId, transId) + ); + } + + @Override + public Page pageList(Page page, AdRecordDto dto) { + Page pageList = baseMapper.selectPage(page, dto); + disposePageList(page.getRecords()); + return pageList; + } + + public void disposePageList(List records) { + if (ObjectUtil.isEmpty(records)) return; + List userIdList = records.stream().map(AdRecordVo::getUserId).distinct().filter(ObjectUtil::isNotNull).toList(); + if (ObjectUtil.isNotEmpty(userIdList)) { + List sysUserList = this.remoteUserService.getUserDeptByIds(userIdList).getData(); + if (ObjectUtil.isNotEmpty(sysUserList)) { + DataUtil.convertUserDeptList(records, CollectionUtils.convertMap(sysUserList, UserVO::getUserId)); + } + } + } + +} \ No newline at end of file diff --git a/pjcloud-integrated/pjcloud-integrated-biz/src/main/resources/mapper/ad/ThirdAdRecordMapper.xml b/pjcloud-integrated/pjcloud-integrated-biz/src/main/resources/mapper/ad/ThirdAdRecordMapper.xml new file mode 100755 index 000000000..7043bf15b --- /dev/null +++ b/pjcloud-integrated/pjcloud-integrated-biz/src/main/resources/mapper/ad/ThirdAdRecordMapper.xml @@ -0,0 +1,53 @@ + + + + + + select a.id, + a.user_id, + a.trans_id, + a.ad_id, + a.ad_type, + a.ad_provider, + a.visit_platform, + a.visit_start_time, + a.visit_end_time, + a.visit_duration, + a.status, + a.extra, + a.create_time, + a.update_time, + a.create_by, + a.update_by, + a.del_flag, + a.tenant_id + + + + a.del_flag = '0' + + and a.user_id = #{dto.userId} + + + and a.trans_id = #{dto.transId} + + + and a.ad_id = #{dto.adId} + + + and a.ad_type = #{dto.adType} + + + and a.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]} + + + + + \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ad/UniappAdCallbackDto.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ad/UniappAdCallbackDto.java new file mode 100644 index 000000000..79e5918e7 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ad/UniappAdCallbackDto.java @@ -0,0 +1,60 @@ +package com.bsd.pjcloud.thirdparty.dto.ad; + +import lombok.Data; + +import java.util.Map; + +@Data +public class UniappAdCallbackDto { + + /** + * 广告位ID + */ + private String adpid; + + /** + * 广告服务商 + */ + private String provider; + + /** + * 平台 + */ + private String platform; + + /** + * 交易id + */ + private String transId; + + /** + * 用户id + */ + private Long userId; + + /** + * 额外参数json + */ + private String extra; + + /** + * cpm/1000则为本次观看收益 + */ + private Integer cpm; + + public static UniappAdCallbackDto mapToEntity(Map map) { + UniappAdCallbackDto dto = new UniappAdCallbackDto(); + try { + dto.setAdpid(map.get("adpid")); + dto.setProvider(map.get("provider")); + dto.setPlatform(map.get("platform")); + dto.setTransId(map.get("trans_id")); + dto.setUserId(Long.parseLong(map.get("user_id"))); + dto.setExtra(map.get("extra")); + dto.setCpm(Integer.parseInt(map.get("cpm"))); + } catch (Exception e) { + e.printStackTrace(); + } + return dto; + } +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/xfj/XfjConsumTransactionsDto.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/xfj/XfjConsumTransactionsDto.java new file mode 100644 index 000000000..9db58f24a --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/xfj/XfjConsumTransactionsDto.java @@ -0,0 +1,72 @@ +package com.bsd.pjcloud.thirdparty.dto.xfj; + +import lombok.Data; + +import java.util.List; + +@Data +public class XfjConsumTransactionsDto { + + /** + * 消费序号(年月日时分秒+2个字节序号(0~65535)),用于识别上传数据不重复 + */ + private String Order; + + /** + * 10进制卡序列号(实体卡号或虚拟卡号) + */ + private String CardNo; + + /** + * 卡模式 + * 0:实体卡 + * 1:电子卡 + */ + private Integer CardMode; + + /** + * 交易模式 + * 0: 刷卡扣费 + * 1: 现金充值 + * 2: 余额查询 + * 3: 钱包转账 + * 4: 现金退款 + */ + private Integer Mode; + + /** + * 扣费类型 + * 0:手动 + * 1:菜单 + * 2:定值 + * 3:取餐 + * 4:计时 + * 5:计次 + */ + private Integer PayType; + + /** + * 消费金额(Mode为2时,此字段传入值可能为0) + */ + private String Amount; + + /** + * 菜品消费列表 + */ + List Menus; + + @Data + static public class Menus { + + /** + * 菜品编号(与菜品查询接口菜品编号一致) + */ + private String MenuID; + + /** + * 菜品数量(支持小数) + */ + private String Count; + + } +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/xfj/XfjServerTimeDto.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/xfj/XfjServerTimeDto.java new file mode 100644 index 000000000..8851ab757 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/xfj/XfjServerTimeDto.java @@ -0,0 +1,18 @@ +package com.bsd.pjcloud.thirdparty.dto.xfj; + +import lombok.Data; + +@Data +public class XfjServerTimeDto { + + /** + * 设备中的总白名单数 + */ + private Integer WLSum; + + /** + * 自定义机号 + */ + private Integer DeviceID; + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjBaseVo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjBaseVo.java new file mode 100644 index 000000000..9243d9ab0 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjBaseVo.java @@ -0,0 +1,19 @@ +package com.bsd.pjcloud.thirdparty.vo.xfj; + +import lombok.Data; + +@Data +public class XfjBaseVo { + + /** + * 1:成功 + * 0:失败 + */ + private String Status; + + /** + * 错误消息(Status为0时屏幕显示此内容,最多不超过8个汉字) + */ + private String Msg; + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjConsumTransactionsVo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjConsumTransactionsVo.java new file mode 100644 index 000000000..eac9d6912 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjConsumTransactionsVo.java @@ -0,0 +1,68 @@ +package com.bsd.pjcloud.thirdparty.vo.xfj; + +import lombok.Data; + +@Data +public class XfjConsumTransactionsVo extends XfjBaseVo { + + /** + * 人员姓名 + */ + private String Name; + + /** + * 10进制卡序列号(实体卡号或虚拟卡号) + */ + private String CardNo; + + /** + * 现金余额(允许两位小数) + */ + private String Money; + + /** + * 补贴余额(允许两位小数) + */ + private String Subsidy; + + /** + * 剩余次数 + */ + private String Times; + + /** + * 赠送余额(允许两位小数) + */ + private String Integral; + + /** + * 入场时间(固定值:"") + */ + private String InTime; + + /** + * 出场时间(固定值:"") + */ + private String OutTime; + + /** + * 累计使用时间:天时分秒 + */ + private String CumulativeTime; + + /** + * 实际扣费金额(信息查询模式下返回"0") + */ + private String Amount; + + /** + * 语音段(用于安卓系统设备) + */ + private String VoiceID; + + /** + * 自定义显示文本(Status为1时传入,屏幕显示此值,内容内使用\r\n换行,最多支持4行,每行不超过8个汉字) + */ + private String Text; + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjServerTimeVo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjServerTimeVo.java new file mode 100644 index 000000000..b6c230f59 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/xfj/XfjServerTimeVo.java @@ -0,0 +1,24 @@ +package com.bsd.pjcloud.thirdparty.vo.xfj; + +import lombok.Data; + +@Data +public class XfjServerTimeVo extends XfjBaseVo { + + /** + * 服务器时间,固定格式为yyyyMMddHHmmssd最后一位d代表星期,星期一为1,星期六为6,星期天为0 + */ + private String Time; + + /** + * 1:有白名单更新 + * 0:无 + */ + private Integer WLUptate; + + /** + * 起始页数(当WLUptate为1却WLPage为0时,清除所有白名单) + */ + private Integer WLPage; + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml index 385884a42..b89bfa465 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/pom.xml @@ -149,6 +149,12 @@ 5.7.0 compile + + com.bsd + pjcloud-integrated-api + 5.7.0 + compile + diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/AdConfig.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/AdConfig.java new file mode 100644 index 000000000..67fbba631 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/config/AdConfig.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.thirdparty.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "ad") +@Data +public class AdConfig { + + /** + * uniapp广告回调secret + */ + private String uniAdCallbackSecret; + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ad/ThirdUniAdController.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ad/ThirdUniAdController.java new file mode 100644 index 000000000..66f7bff0d --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ad/ThirdUniAdController.java @@ -0,0 +1,79 @@ +package com.bsd.pjcloud.thirdparty.controller.ad; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSON; +import cn.hutool.json.JSONUtil; +import com.bsd.pjcloud.common.security.annotation.Inner; +import com.bsd.pjcloud.integrated.api.feign.RemoterIntegratedAdService; +import com.bsd.pjcloud.thirdparty.config.AdConfig; +import com.bsd.pjcloud.thirdparty.dto.ad.UniappAdCallbackDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.collections4.map.HashedMap; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/third-uni-ad") +@Tag(description = "third-uni-ad", name = "uniapp广告") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class ThirdUniAdController { + + final private AdConfig adConfig; + + final private RemoterIntegratedAdService remoterIntegratedAdService; + + @Inner(value = false) + @GetMapping("/callback") + @Operation(summary = "uniapp广告回调", description = "uniapp广告回调") + public Map checkSystemStatus(HttpServletRequest request) { + Map result = new HashedMap<>(); + result.put("isValid", false); + + Map params = new LinkedHashMap<>(); + Map parameterMap = request.getParameterMap(); + for (Map.Entry entry : parameterMap.entrySet()) { + String key = entry.getKey(); + List value = Arrays.asList(entry.getValue()); + if (value.size() == 1) { + params.put(key, value.get(0)); + } + } + // 校验sign + if (ObjectUtil.isEmpty(params) || ObjectUtil.isEmpty(params.get("sign")) || ObjectUtil.isEmpty(params.get("trans_id"))) { + log.error("|uniapp ad 回调错误|回调参数错误params:{}", JSONUtil.toJsonStr(params)); + return result; + } + String computeSign = DigestUtils.sha256Hex(String.format("%s:%s", adConfig.getUniAdCallbackSecret(), params.get("trans_id"))); + String sign = params.get("sign"); + if (ObjectUtil.notEqual(computeSign, sign)) { + log.error("|uniapp ad 回调错误|sign错误sign:{}computeSign:{}", sign, computeSign); + return result; + } + // 对参数进行处理 + UniappAdCallbackDto dto = UniappAdCallbackDto.mapToEntity(params); + // 调用广告模块 + Boolean res = remoterIntegratedAdService.uniappAdCallback(dto).getData(); + if (ObjectUtil.isNotEmpty(res) && res) { + result.put("isValid", true); + } + return result; + } + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/xfj/ThirdXfjController.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/xfj/ThirdXfjController.java new file mode 100644 index 000000000..b67a1241f --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/xfj/ThirdXfjController.java @@ -0,0 +1,20 @@ +package com.bsd.pjcloud.thirdparty.controller.xfj; + +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 消费机api接口 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/third-xfj") +@Tag(description = "third-xfj", name = "消费机接口") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class ThirdXfjController { + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdXfjThirdService.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdXfjThirdService.java new file mode 100644 index 000000000..459c6ad99 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdXfjThirdService.java @@ -0,0 +1,6 @@ +package com.bsd.pjcloud.thirdparty.service; + + +public interface ThirdXfjThirdService { + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ad/ThirdXfjThirdServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ad/ThirdXfjThirdServiceImpl.java new file mode 100644 index 000000000..acca62cb4 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/ad/ThirdXfjThirdServiceImpl.java @@ -0,0 +1,15 @@ +package com.bsd.pjcloud.thirdparty.service.impl.ad; + +import com.bsd.pjcloud.thirdparty.service.ThirdXfjThirdService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +@Service +@Validated +@Slf4j +@RequiredArgsConstructor +public class ThirdXfjThirdServiceImpl implements ThirdXfjThirdService { + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml index 41863b775..a8c4abc6a 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml @@ -103,6 +103,9 @@ zy: # company-number: 202504673472 # sm4-key: 63P839eg0uxE5aoG +ad: + uni-ad-callback-secret: 18200af9d0c84670747e920a66ec09cda0962bc8f42f23431c7dc52bca17e226 + sms: api: diff --git a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/SysUser.java b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/SysUser.java index 29e2f6028..093d2076a 100644 --- a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/SysUser.java +++ b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/entity/SysUser.java @@ -257,4 +257,16 @@ public class SysUser extends Model implements Serializable { */ @Schema(description = "编制类型") private String staffingType; + + /** + * 是否注销 + */ + @Schema(description = "是否注销") + private String closeAccountFlag; + + /** + * 注销账户申请时间 + */ + @Schema(description = "注销账户申请时间") + private LocalDateTime closeAccountApplyTime; } diff --git a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/vo/UserVO.java b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/vo/UserVO.java index a0315c920..ed07e253b 100644 --- a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/vo/UserVO.java +++ b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/vo/UserVO.java @@ -246,4 +246,16 @@ public class UserVO implements BaseFacesInterface, Serializable { * 编制类型 */ private String staffingType; + + /** + * 是否注销 + */ + @Schema(description = "是否注销") + private String closeAccountFlag; + + /** + * 注销账户申请时间 + */ + @Schema(description = "注销账户申请时间") + private LocalDateTime closeAccountApplyTime; } diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/PjcloudAdminApplication.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/PjcloudAdminApplication.java index e4369bb02..8013aea61 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/PjcloudAdminApplication.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/PjcloudAdminApplication.java @@ -24,6 +24,7 @@ import com.bsd.pjcloud.common.swagger.annotation.EnableOpenApi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.scheduling.annotation.EnableScheduling; /** * @author pjcloud @@ -34,6 +35,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableOpenApi("admin") @EnablePjcloudResourceServer @EnableDiscoveryClient +@EnableScheduling @SpringBootApplication public class PjcloudAdminApplication { diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/RegisterController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/RegisterController.java index 6a5c5a410..ae3a9389d 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/RegisterController.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/RegisterController.java @@ -39,6 +39,14 @@ public class RegisterController { // return userService.registerUser(userDto); // } + /** + * 注册普通用户 + */ + @SysLog("注册用户") + @PostMapping("/default-user") + public R registerDefaultUser(@RequestBody UserDTO userDto) { + return R.ok(userService.registerDefaultUser(userDto)); + } /** diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysDeptController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysDeptController.java index 2eb197650..7033bd0a6 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysDeptController.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysDeptController.java @@ -96,6 +96,15 @@ public class SysDeptController { return R.ok(sysDeptService.selectTree(deptName, parentId, user)); } + /** + * 返回树形菜单集合 + */ + @GetMapping(value = "/tree/v2") + public R getTreeV2(String deptName, Long parentId) { + PjcloudUser user = SecurityUtils.getUser(); + return R.ok(sysDeptService.selectTreeV2(deptName, parentId, user)); + } + /** * 查询所有,无权限过滤 * simpleTree @@ -110,7 +119,6 @@ public class SysDeptController { } - /** * 添加 * diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java index c69cafa62..f35e137f6 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserController.java @@ -46,6 +46,7 @@ import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; import com.bsd.pjcloud.common.log.annotation.SysLog; import com.bsd.pjcloud.common.security.annotation.HasPermission; import com.bsd.pjcloud.common.security.annotation.Inner; +import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.common.security.util.SecurityUtils; import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto; @@ -105,6 +106,16 @@ public class SysUserController { /* ************************************* end 回调 end ************************************* */ + + /** + * 申请注销 + */ + @PostMapping("/app/apply/close-account") + public R appApplyCloseAccount() { + PjcloudUser user = SecurityUtils.getUser(); + return R.ok(userService.applyCloseAccount(user.getId())); + } + /** * 获取指定用户全部信息 * diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysDeptService.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysDeptService.java index 212444e7a..bba5f096f 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysDeptService.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysDeptService.java @@ -52,6 +52,8 @@ public interface SysDeptService extends IService { */ List> selectTree(String deptName, Long parentId, PjcloudUser user); + List> selectTreeV2(String deptName, Long parentId, PjcloudUser user); + List> selectSimpleTree(String deptName, Long parentId); /** diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserService.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserService.java index 16fd28f7d..857d06bb0 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserService.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserService.java @@ -41,6 +41,11 @@ import java.util.List; */ public interface SysUserService extends IService { + /** + * 申请注销用户 + */ + Boolean applyCloseAccount(Long userId); + /** * 查询用户信息 * @@ -136,6 +141,11 @@ public interface SysUserService extends IService { */ R registerUser(UserDTO userDto); + /** + * 注册普通用户 + */ + Boolean registerDefaultUser(UserDTO userDto); + /** * 锁定用户 * diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysDeptServiceImpl.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysDeptServiceImpl.java index aa114d5d3..59d33ce5b 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysDeptServiceImpl.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysDeptServiceImpl.java @@ -146,9 +146,21 @@ public class SysDeptServiceImpl extends ServiceImpl impl .map(SysDept::getDeptId) .toList(); + + List> build = TreeUtil.build(deptAllList.stream().map(dept -> { + TreeNode treeNode = new TreeNode<>(); + treeNode.setId(dept.getDeptId()); + treeNode.setParentId(dept.getParentId()); + treeNode.setName(dept.getName()); + treeNode.setWeight(dept.getSortOrder()); + return treeNode; + }).toList(), 0L); + + // 权限内部门 List> collect = deptAllList.stream() .filter(dept -> dept.getDeptId().intValue() != dept.getParentId()) + .filter(dept -> deptOwnIdList.contains(dept.getDeptId()) || ObjectUtil.equals(dept.getParentId(), 0L)) .sorted(Comparator.comparingInt(SysDept::getSortOrder)) .map(dept -> { TreeNode treeNode = new TreeNode<>(); @@ -186,6 +198,48 @@ public class SysDeptServiceImpl extends ServiceImpl impl return tree; } + @Override + public List> selectTreeV2(String deptName, Long parentId, PjcloudUser user) { + // 查询全部部门 + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName); + List deptAllList = deptMapper.selectList(queryWrapper); + List> deptAllTree = TreeUtil.build(deptAllList.stream().map(dept -> { + TreeNode treeNode = new TreeNode<>(); + treeNode.setId(dept.getDeptId()); + treeNode.setParentId(dept.getParentId()); + treeNode.setName(dept.getName()); + treeNode.setWeight(dept.getSortOrder()); + return treeNode; + }).toList(), 0L); + Tree currentDeptTree = null; + for (Tree rootNode : deptAllTree) { + currentDeptTree = TreeUtil.getNode(rootNode, user.getDeptId()); + if (currentDeptTree != null) { + break; + } + } + List> currentDeptAllNodes = getSubTreeNodes(currentDeptTree); + return currentDeptAllNodes; + } + + public List> getSubTreeNodes(Tree node) { + List> result = new ArrayList<>(); + collect(node, result); + return result; + } + + private void collect(Tree node, List> result) { + if (node == null) { + return; + } + result.add(node); + if (node.getChildren() != null) { + for (Tree child : node.getChildren()) { + collect(child, result); + } + } + } + /** * 如果都是在targetDeptId这树上的visible都为true */ diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java index 6b3cc21f2..d25e4dc53 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java @@ -53,6 +53,7 @@ import com.bsd.pjcloud.common.audit.annotation.Audit; import com.bsd.pjcloud.common.core.constant.CacheConstants; import com.bsd.pjcloud.common.core.constant.CommonConstants; import com.bsd.pjcloud.common.core.constant.CommonRoleConstant; +import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum; import com.bsd.pjcloud.common.core.exception.ErrorCodes; import com.bsd.pjcloud.common.core.util.CollectionUtils; import com.bsd.pjcloud.common.core.util.MsgUtils; @@ -130,11 +131,27 @@ public class SysUserServiceImpl extends ServiceImpl impl private final FlowUtil flowUtil; + /** + * 申请注销用户 + */ + @Override + public Boolean applyCloseAccount(Long userId) { + SysUser sysUser = baseMapper.selectById(userId); + if (ObjectUtil.isEmpty(sysUser)) { + throw new RuntimeException("用户不存在"); + } + if (ObjectUtil.equals(sysUser.getCloseAccountFlag(), YesNoEnum.YES.getCode())) { + throw new RuntimeException("您已注销"); + } + SysUser updateObj = new SysUser(); + updateObj.setUserId(userId); + updateObj.setCloseAccountFlag(YesNoEnum.NO.getCode()); + updateObj.setCloseAccountApplyTime(LocalDateTime.now()); + return baseMapper.updateById(updateObj) > 0; + } + /** * 保存用户信息 - * - * @param userDto DTO 对象 - * @return success/fail */ @Override @Transactional(rollbackFor = Exception.class) @@ -753,6 +770,71 @@ public class SysUserServiceImpl extends ServiceImpl impl return R.ok(true); } + /** + * 注册普通用户 + */ + @Override + public Boolean registerDefaultUser(UserDTO userDto) { + userDto.setPhone(userDto.getUsername()); + // 判断用户名是否存在 + boolean usernameExists = this.exists(Wrappers.lambdaQuery().eq(SysUser::getUsername, userDto.getUsername())); + if (usernameExists) { + String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername()); + throw new RuntimeException(message); + } + // 判断手机号是否存在 + boolean phoneExists = this.exists(Wrappers.lambdaQuery().eq(SysUser::getPhone, userDto.getPhone())); + if (phoneExists) { + String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone()); + throw new RuntimeException(message); + } + SysUser sysUser = new SysUser(); + BeanUtils.copyProperties(userDto, sysUser); + + sysUser.setLockFlag(UserStateEnum.NORMAL.getCode()); + sysUser.setCreateBy(userDto.getUsername()); + sysUser.setUpdateBy(userDto.getUsername()); + sysUser.setPassword(ENCODER.encode(userDto.getPassword())); + sysUser.setPasswordModifyTime(LocalDateTime.now()); + sysUser.setProcessStatus(TaskCheckStatusEnum.RESULT.getCode()); + sysUser.setProcessTime(LocalDateTime.now()); + sysUser.setStaffingType(UserStaffingTypeEnum.NONE_STAFFING.getType()); + baseMapper.insert(sysUser); + + // 如果角色为空,赋默认角色 + if (CollUtil.isEmpty(userDto.getRole())) { + // 获取默认角色编码 + String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE"); + // 默认角色 + SysRole sysRole = sysRoleService.getOne(Wrappers.lambdaQuery().eq(SysRole::getRoleCode, defaultRole)); + userDto.setRole(Collections.singletonList(sysRole.getRoleId())); + } + + // 插入用户角色关系表 + userDto.getRole().stream().map(roleId -> { + SysUserRole userRole = new SysUserRole(); + userRole.setUserId(sysUser.getUserId()); + userRole.setRoleId(roleId); + return userRole; + }).forEach(sysUserRoleMapper::insert); + + // 创建用户默认钱包、保证线程header + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + CompletableFuture.runAsync(() -> { + try { + RequestContextHolder.setRequestAttributes(requestAttributes); + // 创建钱包 + remoteWalletService.createWallet(sysUser.getUserId()); + // 通知钱包 + remoteWalletService.userChange(sysUser.getUserId(), Boolean.FALSE); + } catch (Exception e) { + log.error("|{}|创建用户钱包失败error:|{}|", TAG, e.getMessage()); + } + }); + + return true; + } + /** * 锁定用户 * diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/task/UserCloseAccountTask.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/task/UserCloseAccountTask.java new file mode 100644 index 000000000..e385418a7 --- /dev/null +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/task/UserCloseAccountTask.java @@ -0,0 +1,56 @@ +package com.bsd.pjcloud.admin.task; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.bsd.pjcloud.admin.api.entity.SysUser; +import com.bsd.pjcloud.admin.service.SysUserService; +import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.util.List; + +/** + * 将申请注销时间超过15天时把他设置为已注销 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class UserCloseAccountTask { + + private final String TAG = "用户定时任务"; + private final SysUserService sysUserService; + + @Scheduled(cron = "0 30 4 * * ?") + public void handleCloseAccount() { + log.info("|{}|开始执行用户注销任务", TAG); + try { + List closeAccountUserList = sysUserService.list(new LambdaQueryWrapper() + .and(wrapper -> wrapper.eq(SysUser::getCloseAccountFlag, YesNoEnum.NO.getCode()).or().isNull(SysUser::getCloseAccountFlag)) + .isNotNull(SysUser::getCloseAccountApplyTime) + .le(SysUser::getCloseAccountApplyTime, LocalDateTimeUtil.format(LocalDate.now().minusDays(15), DatePattern.NORM_DATETIME_PATTERN)) + ); + if (ObjectUtil.isEmpty(closeAccountUserList)) { + log.info("|{}|没有需要注销的用户", TAG); + return; + } + List updateList = closeAccountUserList.stream().map(user -> { + SysUser sysUser = new SysUser(); + sysUser.setUserId(user.getUserId()); + sysUser.setLockFlag(YesNoEnum.YES.getCode()); + sysUser.setCloseAccountFlag(YesNoEnum.YES.getCode()); + return sysUser; + }).toList(); + sysUserService.updateBatchById(updateList); + log.info("|{}|注销用户成功,共{}个", TAG, updateList.size()); + } catch (Exception e) { + log.error("|{}|执行用户注销任务时发生错误", TAG, e); + } + } + +} diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserMapper.xml b/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserMapper.xml index def99ddc4..054ecbbad 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserMapper.xml +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserMapper.xml @@ -94,7 +94,10 @@ - u.user_id, + u + . + user_id + , u.username, u.password, u.salt, @@ -118,6 +121,8 @@ u.create_time ucreate_time, u.update_time uupdate_time, u.staffing_type, + u.close_account_flag, + u.close_account_apply_time, d.name dept_name, d.dept_id @@ -173,6 +178,8 @@ u.email, u.is_global_face, u.staffing_type, + u.close_account_flag, + u.close_account_apply_time, d.name dept_name FROM sys_user u @@ -270,6 +277,8 @@ u.name, u.email, u.staffing_type, + u.close_account_flag, + u.close_account_apply_time, d.name dept_name FROM sys_user u