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