Merge remote-tracking branch 'origin/master'

This commit is contained in:
zjf committed 2026-02-02 17:24:51 +08:00
commit 32702677fd
182 files changed
+7907 -625

No files matched your search

+23
View File
@@ -13,3 +13,26 @@ CREATE TABLE `hard_panel_setting`
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='大屏配置表';
-- app版本控制表
CREATE TABLE `app_version`
(
`id` bigint NOT NULL COMMENT '主键ID',
`app_unique_code` varchar(32) DEFAULT NULL COMMENT 'app唯一编码',
`platform` varchar(32) NOT NULL COMMENT '平台类型(android、ios)',
`version_code` int NOT NULL COMMENT '内部版本号(用于比较大小)',
`version_name` varchar(32) NOT NULL COMMENT '展示版本号(字符串)',
`update_content` text COMMENT '更新内容/更新日志',
`download_url` varchar(512) NOT NULL COMMENT '安装包下载地址(wgt、apk)',
`is_force` varchar(32) NOT NULL COMMENT '是否强制更新',
`is_silent` varchar(32) NOT NULL COMMENT '是否静默更新(WGT用)',
`status` varchar(32) NOT NULL COMMENT '状态(已发布、未发布、已下架)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0' COMMENT '是否删除(0=正常 1=删除)',
`tenant_id` bigint(20) DEFAULT NULL COMMENT '租户编号',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='app版本控制表';
+43
View File
@@ -0,0 +1,43 @@
CREATE OR REPLACE VIEW pjcloudx_wallet.v_mch_dept_tree AS
WITH RECURSIVE
root AS (SELECT m.dept_id AS root_dept_id,
m.id AS mch_id,
m.name AS mch_name
FROM pjcloudx_wallet.mch_manage AS m
JOIN pjcloudx.sys_dept AS d
ON d.dept_id = m.dept_id
AND d.del_flag = '0'
WHERE m.del_flag = '0'
AND m.types = '1'),
r (dept_id, parent_id, dept_name, root_dept_id, mch_id, mch_name, level) AS (SELECT d.dept_id,
d.parent_id,
d.name,
root.root_dept_id,
root.mch_id,
root.mch_name,
0
FROM pjcloudx.sys_dept AS d
JOIN root
ON root.root_dept_id = d.dept_id
WHERE d.del_flag = '0'
UNION ALL
SELECT c.dept_id,
c.parent_id,
c.name,
r.root_dept_id,
r.mch_id,
r.mch_name,
r.level + 1
FROM pjcloudx.sys_dept AS c
JOIN r
ON c.parent_id = r.dept_id
WHERE c.del_flag = '0')
SELECT root_dept_id AS mchDeptId,
mch_id AS mchId,
mch_name AS mchName,
dept_id AS deptId,
parent_id AS parentId,
dept_name AS deptName,
level AS level
FROM r
ORDER BY mchDeptId, level, deptId;
+29 -1
View File
@@ -571,4 +571,32 @@ CREATE TABLE hard_spu_repertory
del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
tenant_id bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (id)
) ENGINE = InnoDB COMMENT ='硬件商品库存更新记录';
) ENGINE = InnoDB COMMENT ='硬件商品库存更新记录';
-- ----------------------------
-- Table structure for hard_third_mi_order
-- ----------------------------
DROP TABLE IF EXISTS hard_third_mi_order;
CREATE TABLE hard_third_mi_order
(
id bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
biz_type tinytext NOT NULL COMMENT '上架类型',
user_id bigint NOT NULL COMMENT '用户id',
auth_id bigint COMMENT '授权id',
flow_id bigint COMMENT '流程id',
order_id bigint COMMENT '订单id',
out_order_no varchar(128) COMMENT '外部订单号',
third_order_no varchar(128) COMMENT '第三方订单号',
create_order_time datetime DEFAULT NULL COMMENT '创建订单时间',
pay_order_time datetime DEFAULT NULL COMMENT '支付时间',
refund_order_time datetime DEFAULT NULL COMMENT '退款时间',
order_status tinyint COMMENT '订单状态',
org_json text COMMENT '原始json数据',
create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
update_time datetime DEFAULT NULL COMMENT '修改时间',
del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
tenant_id bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (id)
) ENGINE = InnoDB COMMENT ='硬件商品免密订单';
+73 -1
View File
@@ -41,4 +41,76 @@ CREATE TABLE act_cancel_item
del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
tenant_id bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (id)
) ENGINE = InnoDB COMMENT ='核销活动项';
) ENGINE = InnoDB COMMENT ='核销活动项';
DROP TABLE IF EXISTS act_coupon;
CREATE TABLE act_coupon
(
id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '优惠券ID',
name VARCHAR(128) NOT NULL COMMENT '优惠券名称',
type VARCHAR(64) NOT NULL COMMENT '优惠券类型 (1:满减券 2:折扣券 3:立减券 4:兑换券)',
face_value INT DEFAULT 0 COMMENT '面额/折扣 (满减/立减单位:分, 折扣单位:百分比)',
min_point INT DEFAULT 0 COMMENT '使用门槛 (满多少分可用, 0表示无门槛)',
total_count INT NOT NULL DEFAULT 0 COMMENT '发行总量 (-1表示不限量)',
surplus_count INT NOT NULL DEFAULT 0 COMMENT '剩余数量',
limit_count INT DEFAULT 1 COMMENT '每人限领数量',
limit_type VARCHAR(32) DEFAULT NULL COMMENT '限领类型 (once:活动期间一次 day:每天 week:每周 month:每月 year:每年)',
valid_type VARCHAR(32) NOT NULL COMMENT '有效期类型 (1:固定日期 2:领取后生效)',
valid_start_time DATETIME DEFAULT NULL COMMENT '有效期开始时间',
valid_end_time DATETIME DEFAULT NULL COMMENT '有效期结束时间',
valid_days INT DEFAULT 0 COMMENT '领取后有效天数',
use_scope_type VARCHAR(32) DEFAULT 0 COMMENT '适用范围 (0:全场通用 1:指定商户 2:指定分类 3:指定商品)',
scope_id VARCHAR(2048) DEFAULT NULL COMMENT '适用范围ID集合 (商户ID/分类ID/商品ID, 逗号分隔)',
status VARCHAR(32) DEFAULT 0 COMMENT '状态 (0:草稿 1:进行中 2:已结束 3:已作废)',
description VARCHAR(512) DEFAULT NULL COMMENT '使用说明',
create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
update_time datetime DEFAULT NULL COMMENT '修改时间',
del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
tenant_id bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (id),
KEY idx_status (status),
KEY idx_valid_end_time (valid_end_time)
) ENGINE = InnoDB COMMENT ='优惠券活动';
DROP TABLE IF EXISTS act_coupon_record;
CREATE TABLE act_coupon_record
(
id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '领取记录ID',
coupon_id BIGINT(20) NOT NULL COMMENT '优惠券ID',
user_id BIGINT(20) NOT NULL COMMENT '用户ID',
user_name VARCHAR(64) DEFAULT NULL COMMENT '用户名称',
coupon_code VARCHAR(64) NOT NULL COMMENT '券码(唯一标识)',
status VARCHAR(32) NOT NULL DEFAULT '0' COMMENT '使用状态 (0:未使用 1:已使用 2:已过期 3:已作废)',
-- 冗余优惠券快照信息,防止优惠券修改后数据不一致
coupon_name VARCHAR(128) NOT NULL COMMENT '优惠券名称',
coupon_type VARCHAR(64) NOT NULL COMMENT '优惠券类型',
face_value INT DEFAULT 0 COMMENT '面额/折扣',
min_point INT DEFAULT 0 COMMENT '使用门槛',
-- 有效期
start_time DATETIME NOT NULL COMMENT '有效开始时间',
end_time DATETIME NOT NULL COMMENT '有效结束时间',
-- 使用信息
use_time DATETIME DEFAULT NULL COMMENT '使用时间',
order_id VARCHAR(64) DEFAULT NULL COMMENT '关联订单号',
use_amount INT DEFAULT 0 COMMENT '抵扣金额(分)',
create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
create_time datetime DEFAULT NULL COMMENT '领取时间',
update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
update_time datetime DEFAULT NULL COMMENT '修改时间',
del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
tenant_id bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (id),
UNIQUE KEY uk_coupon_code (coupon_code),
KEY idx_user_id (user_id),
KEY idx_coupon_id (coupon_id),
KEY idx_end_time (end_time),
KEY idx_status (status)
) ENGINE = InnoDB COMMENT ='优惠券领取记录表';
@@ -0,0 +1,27 @@
package com.bsd.pjcloud.app.api.constant;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* app用户类型
*/
@AllArgsConstructor
@Getter
public enum AppUserTypeEnum {
MINI_WECHAT("10", "微信小程序用户"),
MINI_ALIPAY("20", "支付宝小程序用户"),
;
private final String type;
private final String description;
public static AppUserTypeEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get();
}
}
@@ -40,122 +40,134 @@ import java.time.LocalDateTime;
@Schema(description = "app用户表")
public class AppUser extends Model<AppUser> {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
/**
* userId
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "userId")
private Long userId;
/**
* userId
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "userId")
private Long userId;
/**
* 用户名
*/
@Schema(description = "用户名")
private String username;
/**
* 用户类型
*/
@Schema(description = "用户类型")
private String userType;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 用户名
*/
@Schema(description = "用户名")
private String username;
/**
* 随机盐
*/
@JsonIgnore
@Schema(description = "随机盐")
private String salt;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 手机号
*/
@Schema(description = "手机号")
private String phone;
/**
* 随机盐
*/
@JsonIgnore
@Schema(description = "随机盐")
private String salt;
/**
* 头像
*/
@Schema(description = "头像")
private String avatar;
/**
* 手机号
*/
@Schema(description = "手机号")
private String phone;
/**
* 昵称
*/
@Schema(description = "拓展字段:昵称")
private String nickname;
/**
* 头像
*/
@Schema(description = "头像")
private String avatar;
/**
* 姓名
*/
@Schema(description = "拓展字段:姓名")
private String name;
/**
* 昵称
*/
@Schema(description = "拓展字段:昵称")
private String nickname;
/**
* 邮箱
*/
@Schema(description = "拓展字段:邮箱")
private String email;
/**
* 姓名
*/
@Schema(description = "拓展字段:姓名")
private String name;
/**
* 创建人
*/
@Schema(description = "创建人")
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 邮箱
*/
@Schema(description = "拓展字段:邮箱")
private String email;
/**
* 修改人
*/
@Schema(description = "修改人")
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
/**
* 第三方登录扩展字段
*/
@Schema(description = "第三方登录扩展字段")
private String loginExtJson;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 创建人
*/
@Schema(description = "创建人")
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 修改人
*/
@Schema(description = "修改人")
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
/**
* 删除标记
*/
@Schema(description = "删除标记,1:已删除,0:正常")
@TableField(fill = FieldFill.INSERT)
@TableLogic
private String delFlag;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 所属租户
*/
@Schema(description = "所属租户", hidden = true)
private Long tenantId;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 最后一次密码修改时间
*/
@Schema(description = "最后一次密码修改时间")
private LocalDateTime lastModifiedTime;
/**
* 删除标记
*/
@Schema(description = "删除标记,1:已删除,0:正常")
@TableField(fill = FieldFill.INSERT)
@TableLogic
private String delFlag;
/**
* 锁定标记
*/
@Schema(description = "锁定标记")
private String lockFlag;
/**
* 所属租户
*/
@Schema(description = "所属租户", hidden = true)
private Long tenantId;
/**
* 微信小程序登录openId
*/
@Schema(description = "微信小程序登录openId")
private String wxOpenid;
/**
* 最后一次密码修改时间
*/
@Schema(description = "最后一次密码修改时间")
private LocalDateTime lastModifiedTime;
/**
* 锁定标记
*/
@Schema(description = "锁定标记")
private String lockFlag;
/**
* openId
*/
@Schema(description = "openId")
private String openid;
}
@@ -27,32 +27,27 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author pjcloud
* @date 2018/6/22
*/
@FeignClient(contextId = "remoteAppUserService", value = ServiceNameConstants.APP_SERVER)
public interface RemoteAppUserService {
/**
* 通过用户名查询用户、角色信息
* @param username 用户名
* @param from 调用标志
* @return R
*/
@NoToken
@GetMapping("/appuser/info/{username}")
R<AppUserInfo> info(@PathVariable("username") String username);
/**
* 通过用户名查询用户、角色信息
*/
@NoToken
@GetMapping("/appuser/info/{username}")
R<AppUserInfo> info(@PathVariable("username") String username);
/**
* 通过社交账号或手机号查询用户、角色信息
* @param inStr appid@code
* @param from 调用标志
* @return
*/
@NoToken
@GetMapping("/appsocial/info/{inStr}")
R<AppUserInfo> social(@PathVariable("inStr") String inStr);
@NoToken
@GetMapping("/appuser/infoByUserId/{userId}")
R<AppUserInfo> infoByUserId(@PathVariable("userId") Long userId);
/**
* 通过社交账号或手机号查询用户、角色信息
*/
@NoToken
@GetMapping("/appsocial/info/{inStr}")
R<AppUserInfo> social(@PathVariable("inStr") String inStr);
}
@@ -104,12 +104,23 @@
<groupId>com.bsd</groupId>
<artifactId>pjcloud-common-swagger</artifactId>
</dependency>
<!-- 引入分布式事务-->
<!-- 引入分布式事务 -->
<dependency>
<groupId>com.bsd</groupId>
<artifactId>pjcloud-common-seata</artifactId>
</dependency>
<!-- 支付宝SDK -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.251.ALL</version>
</dependency>
<!-- 微信登录(小程序) -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
<version>4.7.0</version>
</dependency>
</dependencies>
<profiles>
@@ -0,0 +1,38 @@
package com.bsd.pjcloud.app.config;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Slf4j
@Configuration
@EnableConfigurationProperties(MiniWechatConf.class)
public class MinWechatConfiguration {
private final MiniWechatConf properties;
@Autowired
public MinWechatConfiguration(MiniWechatConf properties) {
this.properties = properties;
}
@Bean
public WxMaService wxMaService() {
WxMaDefaultConfigImpl wxMaDefaultConfig = new WxMaDefaultConfigImpl();
wxMaDefaultConfig.setAppid(properties.getAppId());
wxMaDefaultConfig.setSecret(properties.getAppSecret());
wxMaDefaultConfig.setMsgDataFormat("JSON");
WxMaService maService = new WxMaServiceImpl();
maService.setWxMaConfig(wxMaDefaultConfig);
return maService;
}
}
@@ -0,0 +1,40 @@
package com.bsd.pjcloud.app.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 支付宝支付配置
*/
@Component
@ConfigurationProperties(prefix = "mini-ali-pay")
@Data
public class MiniAlipayConf {
/**
* 应用ID
*/
private String appId;
/**
* 私钥
*/
private String privateKey;
/**
* 公钥
*/
private String publicKey;
/**
* 支付宝公钥
*/
private String alipayPublicKey;
/**
* 回调地址
*/
private String callbackUrl;
}
@@ -0,0 +1,18 @@
package com.bsd.pjcloud.app.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 微信小程序配置
*/
@Data
@ConfigurationProperties(prefix = "mini-wechat-pay")
public class MiniWechatConf {
/**
* 应用ID
*/
private String appId;
private String appSecret;
}
@@ -28,6 +28,8 @@ 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 io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
@@ -45,95 +47,79 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class AppSocialDetailsController {
private final AppSocialDetailsService appSocialDetailsService;
private final AppSocialDetailsService appSocialDetailsService;
/**
* 社交登录账户简单分页查询
* @param page 分页对象
* @param appSocialDetails 社交登录
* @return
*/
@GetMapping("/page")
public R getSocialDetailsPage(Page page, AppSocialDetails appSocialDetails) {
return R.ok(appSocialDetailsService.page(page, Wrappers.query(appSocialDetails)));
}
/**
* 社交登录账户简单分页查询
*/
@GetMapping("/page")
public R getSocialDetailsPage(Page page, AppSocialDetails appSocialDetails) {
return R.ok(appSocialDetailsService.page(page, Wrappers.query(appSocialDetails)));
}
/**
* 信息
* @param id id
* @return R
*/
@GetMapping("/{id}")
public R getinfo(@PathVariable("id") Long id) {
return R.ok(appSocialDetailsService.getById(id));
}
/**
* 信息
*/
@GetMapping("/{id}")
public R getinfo(@PathVariable("id") Long id) {
return R.ok(appSocialDetailsService.getById(id));
}
/**
* 保存
* @param appSocialDetails
* @return R
*/
@SysLog("保存三方信息")
@PostMapping
@HasPermission("app_social_details_add")
public R save(@Valid @RequestBody AppSocialDetails appSocialDetails) {
return R.ok(appSocialDetailsService.save(appSocialDetails));
}
/**
* 保存
*/
@SysLog("保存三方信息")
@PostMapping
@HasPermission("app_social_details_add")
public R save(@Valid @RequestBody AppSocialDetails appSocialDetails) {
return R.ok(appSocialDetailsService.save(appSocialDetails));
}
/**
* 修改
* @param appSocialDetails
* @return R
*/
@SysLog("修改三方信息")
@PutMapping
@HasPermission("app_social_details_edit")
public R updateById(@Validated({ ValidGroup.Update.class }) @RequestBody AppSocialDetails appSocialDetails) {
appSocialDetailsService.updateById(appSocialDetails);
return R.ok(Boolean.TRUE);
}
/**
* 修改
*/
@SysLog("修改三方信息")
@PutMapping
@HasPermission("app_social_details_edit")
public R updateById(@Validated({ValidGroup.Update.class}) @RequestBody AppSocialDetails appSocialDetails) {
appSocialDetailsService.updateById(appSocialDetails);
return R.ok(Boolean.TRUE);
}
/**
* 删除
* @param ids
* @return R
*/
@SysLog("删除三方信息")
@DeleteMapping
@HasPermission("app_social_details_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appSocialDetailsService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 删除
*/
@SysLog("删除三方信息")
@DeleteMapping
@HasPermission("app_social_details_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appSocialDetailsService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 通过社交账号、手机号查询用户、角色信息
* @param inStr appid@code
* @return
*/
@Inner
@GetMapping("/info/{inStr}")
public R getUserInfo(@PathVariable String inStr) {
return R.ok(appSocialDetailsService.getUserInfo(inStr));
}
/**
* 通过社交账号、手机号查询用户、角色信息
*/
@Inner
@GetMapping("/info/{inStr}")
public R getUserInfo(@PathVariable String inStr) {
return R.ok(appSocialDetailsService.getUserInfo(inStr));
}
/**
* 绑定社交账号
* @param state 类型
* @param code code
* @return
*/
@PostMapping("/bind")
public R bindSocial(String state, String code) {
return R.ok(appSocialDetailsService.bindSocial(state, code));
}
/**
* 绑定社交账号
*/
@PostMapping("/bind")
public R bindSocial(String state, String code) {
return R.ok(appSocialDetailsService.bindSocial(state, code));
}
/**
* 导出
*/
@GetMapping("/export")
@ResponseExcel
public List<AppSocialDetails> export(AppSocialDetails appSocialDetails) {
return appSocialDetailsService.list(Wrappers.query(appSocialDetails));
}
/**
* 导出
*/
@GetMapping("/export")
@ResponseExcel
public List<AppSocialDetails> export(AppSocialDetails appSocialDetails) {
return appSocialDetailsService.list(Wrappers.query(appSocialDetails));
}
}
@@ -24,6 +24,7 @@ import com.bsd.pjcloud.admin.api.dto.UserTokenDTO;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.feign.RemoteTokenService;
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
import com.bsd.pjcloud.app.api.dto.AppUserDTO;
import com.bsd.pjcloud.app.service.AppUserService;
import com.bsd.pjcloud.canteen.api.feign.RemoteCanteenSpuService;
import com.bsd.pjcloud.canteen.api.feign.RemoteDailyMenuService;
@@ -33,6 +34,7 @@ import com.bsd.pjcloud.canteen.entity.CanteenSpuEntity;
import com.bsd.pjcloud.canteen.vo.app.CanteenOnlineSpuAppVO;
import com.bsd.pjcloud.canteen.vo.app.DailyMenuAppVO;
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.thirdparty.api.feign.RemoterThirdPartyAuthService;
import com.bsd.pjcloud.thirdparty.dto.SHJNSSODTO;
@@ -387,12 +389,13 @@ public class AppUserAutoLoginController {
// return appUserService.importUser(excelVOList, bindingResult);
// }
//
// @Operation(summary = "注册app用户表", description = "注册app用户表")
// @SysLog("注册app用户表")
// @Inner(value = false)
// @PostMapping("/register")
// public R register(@RequestBody AppUserDTO appUser) {
// return appUserService.registerAppUser(appUser);
// }
//@Operation(summary = "注册app用户表", description = "注册app用户表")
//@SysLog("注册app用户表")
//@Inner(value = false)
//@PostMapping("/register")
//public R register(@RequestBody AppUserDTO appUser) {
// return appUserService.registerAppUser(appUser);
//}
}
@@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
import com.bsd.pjcloud.app.api.dto.AppUserDTO;
import com.bsd.pjcloud.app.api.dto.AppUserInfo;
import com.bsd.pjcloud.app.api.entity.AppUser;
import com.bsd.pjcloud.app.api.feign.RemoteAppUserService;
import com.bsd.pjcloud.app.api.vo.AppUserExcelVO;
@@ -61,155 +62,115 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class AppUserController {
private final AppUserService appUserService;
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query()
.lambda()
.eq(AppUser::getUsername, username)
.or()
.eq(AppUser::getPhone, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.APP_USER_USERINFO_EMPTY, username));
}
return R.ok(appUserService.findUserInfo(user));
}
/**
* 获取当前用户全部信息
* @return 用户信息
*/
@GetMapping(value = { "/info" })
public R info() {
String username = SecurityUtils.getUser().getUsername();
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getUsername, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR));
}
return R.ok(appUserService.findUserInfo(user));
}
/**
* 分页查询
* @param page 分页对象
* @param appUserDTO app用户表
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getAppUserPage(Page page, AppUserDTO appUserDTO) {
return R.ok(appUserService.getUsersWithRolePage(page, appUserDTO));
}
/**
* 通过id查询app用户表
* @param userId id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/details/{userId}")
public R getById(@PathVariable("userId") Long userId) {
return R.ok(appUserService.selectUserVoById(userId));
}
/**
* @return R
*/
@Operation(summary = "通过userName查询", description = "通过userName查询")
@GetMapping("/details")
public R getByUserName(AppUser user) {
AppUser one = appUserService.getOne(Wrappers.query(user), false);
return R.ok(one == null ? null : CommonConstants.SUCCESS);
}
/**
* 新增app用户表
* @param appUser app用户表
* @return R
*/
// @Operation(summary = "新增app用户表", description = "新增app用户表")
// @SysLog("新增app用户表")
// @PostMapping
// @HasPermission("app_appuser_add")
// public R save(@RequestBody AppUserDTO appUser) {
// appUserService.saveUser(appUser);
// return R.ok();
// }
/**
* 修改app用户表
* @param appUser app用户表
* @return R
*/
@Operation(summary = "修改app用户表", description = "修改app用户表")
@SysLog("修改app用户表")
@PutMapping
@HasPermission("app_appuser_edit")
public R updateById(@RequestBody AppUserDTO appUser) {
return R.ok(appUserService.updateUser(appUser));
}
/**
* 通过id删除app用户表
* @param ids userIds
* @return R
*/
@Operation(summary = "通过ids删除app用户表", description = "通过ids删除app用户表")
@SysLog("通过id删除app用户表")
@DeleteMapping
@HasPermission("app_appuser_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appUserService.deleteAppUserByIds(ids));
}
/**
* 导出excel 表格
// * @param appUser 查询条件
* @return excel 文件流
*/
// @ResponseExcel
// @GetMapping("/export")
// @HasPermission("app_appuser_export")
// public List<AppUserExcelVO> export(AppUserDTO appUser) {
// return appUserService.listUser(appUser);
// }
@SysLog("修改个人信息")
@PutMapping("/edit")
public R updateUserInfo(@Valid @RequestBody AppUserDTO userDto) {
if (UserTypeEnum.TOC.getStatus().equals(SecurityUtils.getUser().getUserType())) {
userDto.setUserId(SecurityUtils.getUser().getId());
// TOC 以手机号为key
userDto.setUsername(SecurityUtils.getUser().getUsername());
}
return appUserService.updateUserInfo(userDto);
}
/**
* 导入用户
* @param excelVOList 用户列表
* @param bindingResult 错误信息列表
* @return R
*/
// @PostMapping("/import")
// @HasPermission("app_appuser_export")
// public R importUser(@RequestExcel List<AppUserExcelVO> excelVOList, BindingResult bindingResult) {
// return appUserService.importUser(excelVOList, bindingResult);
// }
// @Operation(summary = "注册app用户表", description = "注册app用户表")
// @SysLog("注册app用户表")
// @Inner(value = false)
// @PostMapping("/register")
// public R register(@RequestBody AppUserDTO appUser) {
// return appUserService.registerAppUser(appUser);
// }
private final AppUserService appUserService;
/* ************************************* start app start ************************************* */
/**
* 获取当前用户全部信息
*/
@GetMapping(value = {"/info"})
public R<AppUserInfo> info() {
Long userId = SecurityUtils.getUser().getId();
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getUserId, userId));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR));
}
return R.ok(appUserService.findUserInfo(user));
}
/* ************************************* end app end ************************************* */
/* ************************************* start 远程调用 start ************************************* */
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query()
.lambda()
.eq(AppUser::getUsername, username)
.or()
.eq(AppUser::getPhone, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.APP_USER_USERINFO_EMPTY, username));
}
return R.ok(appUserService.findUserInfo(user));
}
@Inner
@GetMapping("/infoByUserId/{userId}")
public R<AppUserInfo> infoByUserId(@PathVariable Long userId) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query()
.lambda()
.eq(AppUser::getUserId, userId)
);
if (user == null) return R.failed();
return R.ok(appUserService.findUserInfo(user));
}
/* ************************************* end 远程调用 end ************************************* */
/**
* 分页查询
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getAppUserPage(Page page, AppUserDTO appUserDTO) {
return R.ok(appUserService.getUsersWithRolePage(page, appUserDTO));
}
/**
* 通过id查询app用户表
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/details/{userId}")
public R getById(@PathVariable("userId") Long userId) {
return R.ok(appUserService.selectUserVoById(userId));
}
/**
* @return R
*/
@Operation(summary = "通过userName查询", description = "通过userName查询")
@GetMapping("/details")
public R getByUserName(AppUser user) {
AppUser one = appUserService.getOne(Wrappers.query(user), false);
return R.ok(one == null ? null : CommonConstants.SUCCESS);
}
/**
* 修改app用户表
*/
@Operation(summary = "修改app用户表", description = "修改app用户表")
@SysLog("修改app用户表")
@PutMapping
@HasPermission("app_appuser_edit")
public R updateById(@RequestBody AppUserDTO appUser) {
return R.ok(appUserService.updateUser(appUser));
}
/**
* 通过id删除app用户表
*/
@Operation(summary = "通过ids删除app用户表", description = "通过ids删除app用户表")
@SysLog("通过id删除app用户表")
@DeleteMapping
@HasPermission("app_appuser_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appUserService.deleteAppUserByIds(ids));
}
@SysLog("修改个人信息")
@PutMapping("/edit")
public R updateUserInfo(@Valid @RequestBody AppUserDTO userDto) {
if (UserTypeEnum.TOC.getStatus().equals(SecurityUtils.getUser().getUserType())) {
userDto.setUserId(SecurityUtils.getUser().getId());
// TOC 以手机号为key
userDto.setUsername(SecurityUtils.getUser().getUsername());
}
return appUserService.updateUserInfo(userDto);
}
}
@@ -0,0 +1,142 @@
package com.bsd.pjcloud.app.handler;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bsd.pjcloud.app.api.constant.AppUserTypeEnum;
import com.bsd.pjcloud.app.api.dto.AppUserInfo;
import com.bsd.pjcloud.app.api.entity.AppUser;
import com.bsd.pjcloud.app.config.MiniAlipayConf;
import com.bsd.pjcloud.app.mapper.AppSocialDetailsMapper;
import com.bsd.pjcloud.app.service.AppUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 支付宝小程序
*/
@Slf4j
@Component("MINI_ALIPAY")
@AllArgsConstructor
public class MiniAlipayLoginHandler extends AbstractLoginHandler {
private final MiniAlipayConf miniAlipayConf;
private final AppUserService appUserService;
private final AppSocialDetailsMapper appSocialDetailsMapper;
static private AlipayClient alipayClient = null;
public AlipayClient getAlipay() {
if (ObjectUtil.isNotEmpty(miniAlipayConf)) return getAlipayClient();
return getAlipayClient();
}
private synchronized AlipayClient getAlipayClient() {
if (alipayClient == null) {
try {
alipayClient = new DefaultAlipayClient(getAlipayConfig());
} catch (Exception e) {
e.printStackTrace();
log.error("初始化支付宝客户端失败error:{}", e.getMessage());
}
}
return alipayClient;
}
private AlipayConfig getAlipayConfig() {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(miniAlipayConf.getAppId());
alipayConfig.setPrivateKey(miniAlipayConf.getPrivateKey());
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(miniAlipayConf.getAlipayPublicKey());
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
return alipayConfig;
}
/**
* 获取支付宝openId
*/
public AlipaySystemOauthTokenResponse getOpenId(String code, String refreshToken) {
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
// 设置刷新令牌
if (ObjectUtil.isNotEmpty(refreshToken)) {
request.setRefreshToken(refreshToken);
request.setGrantType("refresh_token");
}
// 设置授权码
if (ObjectUtil.isNotEmpty(code)) {
request.setCode(code);
request.setGrantType("authorization_code");
}
try {
AlipaySystemOauthTokenResponse response = getAlipay().execute(request);
if (!response.isSuccess()) {
log.error("|获取支付宝openId|错误error:{}", response.getSubMsg());
}
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|获取支付宝openId|意外的错误error:{}", e.getMessage());
return null;
}
}
/**
* 通过用户传入获取唯一标识
*/
@Override
public String identify(String loginStr) {
AlipaySystemOauthTokenResponse res = getOpenId(loginStr, null);
if (ObjectUtil.isEmpty(res) || ObjectUtil.isEmpty(res.getOpenId())) {
return null;
}
return res.getOpenId();
}
/**
* 获取用户信息
*/
@Override
public AppUserInfo info(String openId) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getOpenid, openId));
if (ObjectUtil.isEmpty(user)) {
log.info("支付宝小程序openId:{},创建新的用户", openId);
String name = "支付宝游客-" + openId;
AppUser appUser = new AppUser();
appUser.setOpenid(openId);
appUser.setUserType(AppUserTypeEnum.MINI_ALIPAY.getType());
appUser.setUsername(name);
appUser.setName(name);
appUser.setCreateBy(openId);
appUser.setUpdateBy(openId);
appUserService.saveOrUpdate(appUser);
return appUserService.findUserInfo(user);
}
if (ObjectUtil.isEmpty(user.getLoginExtJson())) {
}
return appUserService.findUserInfo(user);
}
/**
* 绑定逻辑
*/
@Override
public Boolean bind(AppUser user, String identify) {
user.setOpenid(identify);
appUserService.updateById(user);
return true;
}
}
@@ -17,18 +17,15 @@
package com.bsd.pjcloud.app.handler;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bsd.pjcloud.app.api.constant.AppUserTypeEnum;
import com.bsd.pjcloud.app.api.dto.AppUserInfo;
import com.bsd.pjcloud.app.api.entity.AppSocialDetails;
import com.bsd.pjcloud.app.api.entity.AppUser;
import com.bsd.pjcloud.app.mapper.AppSocialDetailsMapper;
import com.bsd.pjcloud.app.service.AppUserService;
import com.bsd.pjcloud.common.core.constant.SecurityConstants;
import com.bsd.pjcloud.common.core.constant.enums.LoginTypeEnum;
import com.bsd.pjcloud.common.core.exception.CheckedException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -36,20 +33,19 @@ import org.springframework.stereotype.Component;
import java.util.Objects;
/**
* @author pjcloud
* @date 2019年11月02日
* <p>
* 微信小程序
*/
@Slf4j
@Component("APP-MINI")
@Component("MINI_WECHAT")
@AllArgsConstructor
public class MiniAppLoginHandler extends AbstractLoginHandler {
public class MiniWechatLoginHandler extends AbstractLoginHandler {
private final AppUserService appUserService;
private final AppSocialDetailsMapper appSocialDetailsMapper;
private final WxMaService wxMaService;
/**
* 小程序登录传入code
* <p>
@@ -60,20 +56,16 @@ public class MiniAppLoginHandler extends AbstractLoginHandler {
*/
@Override
public String identify(String code) {
AppSocialDetails condition = new AppSocialDetails();
condition.setType(LoginTypeEnum.MINI_APP.getType());
AppSocialDetails socialDetails = appSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
String url = String.format(SecurityConstants.MINI_APP_AUTHORIZATION_CODE_URL, socialDetails.getAppId(),
socialDetails.getAppSecret(), code);
String result = HttpUtil.get(url);
log.debug("微信小程序响应报文:{}", result);
if (JSONUtil.parseObj(result).containsKey("openid")) {
return JSONUtil.parseObj(result).get("openid").toString();
} else {
log.error("微信小程序登录失败:{}", result);
throw new CheckedException("微信小程序登录失败");
try {
WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
if (ObjectUtil.isNotEmpty(session) && ObjectUtil.isNotEmpty(session.getOpenid())) {
return session.getOpenid();
}
return null;
} catch (Exception e) {
e.printStackTrace();
log.error("微信小程序登录失败:{}", e.getMessage());
return null;
}
}
@@ -85,23 +77,23 @@ public class MiniAppLoginHandler extends AbstractLoginHandler {
*/
@Override
public AppUserInfo info(String openId) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getWxOpenid, openId));
// 未注册用户自动注册
if (Objects.isNull(user)) {
log.info("微信小程序未绑定:{},创建新的用户", openId);
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getOpenid, openId));
if (ObjectUtil.isEmpty(user)) {
log.info("微信小程序openId:{},创建新的用户", openId);
String name = "微信游客-" + openId;
AppUser appUser = new AppUser();
appUser.setWxOpenid(openId);
appUser.setUsername(openId);
appUser.setOpenid(openId);
appUser.setUserType(AppUserTypeEnum.MINI_ALIPAY.getType());
appUser.setUsername(name);
appUser.setName(name);
appUser.setCreateBy(openId);
appUser.setUpdateBy(openId);
appUserService.saveOrUpdate(appUser);
AppUserInfo appUserDTO = new AppUserInfo();
appUserDTO.setAppUser(appUser);
return appUserDTO;
return appUserService.findUserInfo(user);
}
if (ObjectUtil.isEmpty(user.getLoginExtJson())) {
}
return appUserService.findUserInfo(user);
}
@@ -114,7 +106,7 @@ public class MiniAppLoginHandler extends AbstractLoginHandler {
*/
@Override
public Boolean bind(AppUser user, String identify) {
user.setWxOpenid(identify);
user.setOpenid(identify);
appUserService.updateById(user);
return true;
}
@@ -16,3 +16,15 @@ spring:
import:
- optional:nacos:application-@profiles.active@.yml
- optional:nacos:${spring.application.name}-@profiles.active@.yml
mini-ali-pay:
app-id: 2021005197658445
private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTYHY0AW2cjbHoOinD8f4CKMKasDmbRw4CEMasG5IzckmeuTqut3GmxxRRls62zlXRVOCDYgnGhzEhD/nMYx0TMBX2mYo+fH9XUMtZMKY+p2rPTXTlPnGfbQ4edUYofR0tq1ug+wHOD5/jxuwO1zPfB7t8dX3gNa4M43fTPK2mPDeo/UiRB45DPjUWvbMX59ltYYMgmAW0TAbXmRAGKFxrmX3HddJK0jSwEpTcHaRV3C6FrYV48vWHEliviVBUsLRIpwv3T3FYZm0a19LcGQtybeThXaaCYrj7Lwoffk8v8DL2g28IAeiFtjjkWbPFKKMCsSe/LVkvdQTuhncuDayTAgMBAAECggEAJvreiMbP7RZ1Nc0cet0op/2L60otEmrqw5UYVzE7rCvQWRD4+nk+sDP7pdDTf/p3LFTcxSNLHp1nWy1UjsCwUgDn7j+SFxDqxXdzMXXyoqO5VndQMcogV2CK2Xd/RPpCm2+1XpDFW3E6gw58JTi6WYU8C6Ev1/uau4H2kYJ9E3h2W0P0PyY+Q9QNHEpG2hLQdiWLHz3xzmSNSDXiknEg/Whew7IMVKNgxg5VVEBTerwCH5Grvn56CKx6acb6JlU+VFsmW3J1tMYLgxVhJWVVAK6NltmxE5apIxTkG3wEOMuuBCZHQ1Lm0rrGKJh8WmYRs6ho5wSjHYG3hyKRm/0TEQKBgQDcDDPyOWw/o9ZqB3N7qxUi63V7wU7X8QL/CmQO4tu/ng/4Drm8QESjk+ib3O3pCC7xwcte/U1Otw3AmSSj1CWvT8a0yLJM9GVOJwZFVyzy6yVFPyn6l4ndRdargyFokM2lgVTgEHo4WSMbLQsA8/KTB3anqo6bYLjqjsBgY49fpQKBgQCrdLMh5ayJOUK9UeBHXr0c/OLDzwoSUVMyNLfX3pIBC21meFxigNMiy+UKpslM2QMH1yyfwsUKv/i7y1kRFj9Go7pYU0HxglfHecllqXPunWJYuSm38x8WWAG/oqcLPGSlJjHYhU6IAkDuHHaW5DKLxr0x2DkZ/c4TcyYal9Ol1wKBgD4Lls4S0On02W1WIoLZT4FkIOE/NWsAAxdEp8fmwY17FQedp1NkT7ZL60efeNm/O/Vg7mYfSCAMz2ziAYnMNMAE34N0H4pBUxtBN6xvkzX/hafL0ptdBTuGCKydsdrZEZM8L2FqY/vlbleoULT5FAnPDe7i0YkQMbO5gpbrG68dAoGAFv+tc7OSREn5CNotwoUTywqlBG0GRdTA2zA1JPDHFvrIbwFgKxpqt/UvwREEWZmWjXuwkbGXqsx7ef1Z8i/QxxH5UhXA97trOOe+OzPSyEQ2R/52eSVUmzOs8F7KF3i/a2PHNesT0Ky0tvv8cFsl6Jf9Eu2VI0ZnWTaN+u04x7sCgYEAlhpr3RSJk2EnLPR3BxKboTxSGsK/2U4xz/WqX96B+lQ5h7NSMJC35vZJ5dm2vHtLcucHaK49YNsJdq+nzhhwxDz+Dd/5rcIp7AcdHqDsVLHYIN7JWxa9QiC3gvrnWsij1DShydOLpGMYveFz0LyRIUDW4CTs55oDFsIR4HdwtM0=
public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk2B2NAFtnI2x6Dopw/H+AijCmrA5m0cOAhDGrBuSM3JJnrk6rrdxpscUUZbOts5V0VTgg2IJxocxIQ/5zGMdEzAV9pmKPnx/V1DLWTCmPqdqz0105T5xn20OHnVGKH0dLatboPsBzg+f48bsDtcz3we7fHV94DWuDON30zytpjw3qP1IkQeOQz41Fr2zF+fZbWGDIJgFtEwG15kQBihca5l9x3XSStI0sBKU3B2kVdwuha2FePL1hxJYr4lQVLC0SKcL909xWGZtGtfS3BkLcm3k4V2mgmK4+y8KH35PL/Ay9oNvCAHohbY45FmzxSijArEnvy1ZL3UE7oZ3Lg2skwIDAQAB
alipay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnCB+N172m5gxf1Rolfx5LErSiVwQCh0XQdDrVy6aTuVF5EtdqahSHtADyEPsBWudMBhzCfqpoZvfnvH7a+PED6uZ3DoXt7ETh8TmNM5yc+WTnD8pSphQvuHDJ3zMks489KNxiX6sXag71k9H1MXklJGPOUaljHqy/QlRn2ZLT7pFgaFH9LEcVoQBPIOurUn95078h848RFD30jZFW3fakxUGAGVVZaHH62z5OEWOmcA+CwxsEDMa1XMt02RGXgAAq4WOj+BqOGiFmhM8rnrUMchTyvx4umOzGvbF2Y9irN3aBZ5lfg+bzYcJpIOMzlM/V00LnEWzCblJzXNyH4hJQIDAQAB
callback-url: https://rj4jv5rwqs.by.takin.cc/hard/hard-ali-pay/callback
# callback-url: https://stgl.pj.gov.cn/api/hard/hard-ali-pay/callback
mini-wechat-pay:
app-id: wx95481f43b14565e5
app-secret: 0aee1289b5ae14c0c69b8f5e9a4e518e
@@ -250,6 +250,16 @@ public interface SecurityConstants {
*/
String APP = "mobile";
/**
* 游客登录(微信,小程序)
*/
String VISITOR = "visitor";
/**
* 游客登录(微信,小程序) openId
*/
String VISITOR_OPEN_ID = "openId";
/**
* 用户信息
*/
@@ -1,22 +1,31 @@
package com.bsd.pjcloud.common.core.constant.enums;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@Getter
@AllArgsConstructor
public enum UserTypeEnum {
TOB("0", "面向后台应用"), TOC("1", "面向小程序");
TOB("0", "面向后台应用"),
TOC("1", "面向小程序");
/**
* 类型
*/
private final String status;
/**
* 类型
*/
private final String status;
/**
* 描述
*/
private final String description;
/**
* 描述
*/
private final String description;
public static UserTypeEnum valueOfByStatus(String status) {
if (ObjectUtil.isEmpty(status)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(status, v.getStatus())).findFirst().orElse(null);
}
}
+1 -1
View File
@@ -33,7 +33,7 @@
<description>pjcloud excel 操作</description>
<properties>
<easyexcel.version>4.0.2</easyexcel.version>
<easyexcel.version>4.0.3</easyexcel.version>
</properties>
<dependencies>
@@ -23,13 +23,13 @@ public enum TaskCheckStatusEnum {
public static TaskCheckStatusEnum descOf(String description) {
return Arrays.stream(TaskCheckStatusEnum.values())
.filter(v -> ObjectUtil.equal(v.getDesc(), description))
.findFirst().get();
.findFirst().orElse(null);
}
public static TaskCheckStatusEnum codeOf(String code) {
return Arrays.stream(TaskCheckStatusEnum.values())
.filter(v -> ObjectUtil.equal(v.getCode(), code))
.findFirst().get();
.findFirst().orElse(null);
}
}
@@ -15,6 +15,7 @@ import java.util.Arrays;
public enum HardAuthTypeEnum {
HARD_DDOR_AUTH("10", "智能柜授权"),
HARD_DDOR_TOC_AUTH("20", "TOC用户智能柜授权"),
;
private final String type;
private final String description;
@@ -0,0 +1,30 @@
package com.bsd.pjcloud.hard.api.constant;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 第三方免密支付状态
*/
@AllArgsConstructor
@Getter
public enum HardThirdMiStatusEnum {
CREATE_ORDER("10", "创建订单"),
PAY_SUCCESS("20", "支付成功"),
PAY_ERROR("21", "支付失败"),
REFUND("30", "取消/退款"),
;
private final String type;
private final String description;
public static HardThirdMiStatusEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get();
}
}
@@ -0,0 +1,28 @@
package com.bsd.pjcloud.hard.api.constant;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 第三方免密类型
*/
@AllArgsConstructor
@Getter
public enum HardThirdMiTypeEnum {
MI_WECHAT("10", "微信免密支付"),
MI_ALIPAY("20", "支付宝-芝麻先享"),
;
private final String type;
private final String description;
public static HardThirdMiTypeEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get();
}
}
@@ -20,6 +20,7 @@ public enum HardOrderTypeEnum {
ZY("5", "正元公务餐"),
LB("6", "宁波银行(美好生活)"),
FARMER("7", "共富商城(助农)"),
TOC_VISITOR("8", "toc访客购买(不记名用户)"),
;
private final String type;
private final String description;
@@ -0,0 +1,26 @@
package com.bsd.pjcloud.hard.api.dto;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class HardAppThirdOpenDoorDto {
/**
* 用户id
*/
private Long userId;
/**
* 用户类型
*/
private UserTypeEnum userType;
/**
* 授权id
*/
@NotNull(message = "授权id不能为空")
private Long authId;
}
@@ -1,5 +1,6 @@
package com.bsd.pjcloud.hard.api.dto;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -12,6 +13,11 @@ public class HardAuthAppDto {
*/
private Long userId;
/**
* 用户类型
*/
private UserTypeEnum userType;
/**
* 授权id
*/
@@ -1,5 +1,6 @@
package com.bsd.pjcloud.hard.api.dto;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -12,6 +13,11 @@ public class HardGetAuthAppDto {
*/
private Long userId;
/**
* 用户类型
*/
private UserTypeEnum userType;
/**
* 智能柜设备id
*/
@@ -0,0 +1,26 @@
package com.bsd.pjcloud.hard.api.dto;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class HardThirdMiOrderDto extends HardThirdMiOrderEntity {
/**
* 创建订单时间
*/
private LocalDateTime[] createOrderTimeList;
/**
* 支付时间
*/
private LocalDateTime[] payOrderTimeList;
/**
* 退款时间
*/
private LocalDateTime[] refundOrderTimeList;
}
@@ -0,0 +1,10 @@
package com.bsd.pjcloud.hard.api.dto;
import lombok.Data;
@Data
public class HardThirdMiPayDto {
private Long id;
}
@@ -0,0 +1,22 @@
package com.bsd.pjcloud.hard.api.dto.hard;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class HandCancelActCodeDto {
@Schema(description = "用户id不能为空")
@NotNull(message = "核销活动子id不能为空")
private Long actItemId;
@Schema(description = "用户id")
@NotNull(message = "用户id不能为空")
private Long userId;
@Schema(description = "设备id")
@NotNull(message = "设备id不能为空")
private Long hardwareId;
}
@@ -11,8 +11,16 @@ public class HardCarDto extends HardCarEntity {
private Long orderId;
/**
* 0 yyyy-MM-dd
* 1 yyyy-MM
*/
private String createTimeType = "0";
private String createTimeStr;
private String createTimeYearStr;
private LocalDate[] createTimeList;
private List<String> orderStatusCodes;
@@ -36,6 +36,12 @@ public class HardOrderDto extends HardOrderEntity implements BaseIsIncludeTreeIn
private List<String> orderStatusCodes;
private String createTimeYearStr;
private String payTimeYearStr;
private String auditTimeYearStr;
private LocalDateTime[] createTimeList;
private LocalDateTime[] payTimeList;
@@ -60,6 +66,12 @@ public class HardOrderDto extends HardOrderEntity implements BaseIsIncludeTreeIn
*/
private String afterSaleNo;
/**
* 0 yyyy-MM-dd
* 1 yyyy-MM
*/
private String createTimeType = "0";
private String createTimeStr;
/**
@@ -0,0 +1,19 @@
package com.bsd.pjcloud.hard.api.dto.order;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class HardSelectOrderMerchIdsDto {
private List<Long> merchIds;
private List<String> merchTypes;
private String payTimeYearStr;
private LocalDateTime[] createTimeList;
}
@@ -37,6 +37,12 @@ public class HardDoorFlowEntity extends Model<HardDoorFlowEntity> {
@Schema(description = "用户编号")
private Long userId;
/**
* 用户类型
*/
@Schema(description = "用户类型")
private String userType;
/**
* 业务类型
*/
@@ -0,0 +1,190 @@
package com.bsd.pjcloud.hard.api.entity;
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("hard_third_mi_order")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "硬件商品免密订单")
public class HardThirdMiOrderEntity extends Model<HardThirdMiOrderEntity> {
/**
* 编号
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "编号")
private Long id;
/**
* 上架类型
*/
@Schema(description = "上架类型")
private String bizType;
/**
* 用户id
*/
@Schema(description = "用户id")
private Long userId;
/**
* 用户类型
*/
@Schema(description = "用户类型")
private String userType;
/**
* 授权id
*/
@Schema(description = "授权id")
private Long authId;
/**
* 流程id
*/
@Schema(description = "流程id")
private Long flowId;
/**
* 订单id
*/
@Schema(description = "订单id")
private Long orderId;
/**
* 退款id
*/
@Schema(description = "退款id")
private Long refundId;
/**
* 设备id
*/
@Schema(description = "设备id")
private Long hardId;
/**
* 外部订单号
*/
@Schema(description = "外部订单号")
private String outOrderNo;
/**
* 第三方订单号
*/
@Schema(description = "第三方订单号")
private String thirdOrderNo;
/**
* 创建订单时间
*/
@Schema(description = "创建订单时间")
private LocalDateTime createOrderTime;
/**
* 支付时间
*/
@Schema(description = "支付时间")
private LocalDateTime payOrderTime;
/**
* 退款时间
*/
@Schema(description = "退款时间")
private LocalDateTime refundOrderTime;
/**
* 订单状态
*/
@Schema(description = "订单状态")
private String orderStatus;
/**
* 押金
*/
@Schema(description = "押金")
private int depositPrice;
/**
* 订单金额
*/
@Schema(description = "订单金额")
private int orderPrice;
/**
* 支付金额
*/
@Schema(description = "支付金额")
private int payPrice;
/**
* 退款金额
*/
@Schema(description = "退款金额")
private int refundPrice;
/**
* 原始 sign json 数据
*/
@Schema(description = "原始 sign json 数据")
private String orgSignJson;
/**
* 原始json数据
*/
@Schema(description = "原始json数据")
private String orgOrderJson;
/**
* 创建人
*/
@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;
/**
* 租户ID
*/
@Schema(description = "租户ID")
private Long tenantId;
}
@@ -78,6 +78,18 @@ public class HardDoorCabinetEntity extends Model<HardDoorCabinetEntity> {
@Schema(description = "url二维码")
private String urlQrCode;
/**
* 支付宝小程序二维码
*/
@Schema(description = "支付宝小程序二维码")
private String urlAlipayQrCode;
/**
* 微信小程序二维码
*/
@Schema(description = "微信小程序二维码")
private String urlWechatQrCode;
/**
* 创建人
*/
@@ -0,0 +1,30 @@
package com.bsd.pjcloud.hard.api.vo;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.vo.base.BaseHardInterface;
import lombok.Data;
import java.util.List;
@Data
public class HardThirdMiOrderVo extends HardThirdMiOrderEntity implements BaseHardInterface {
/**
* 用户相关
*/
private String username;
private String userMobile;
private String userAvatar;
/**
* 设备相关
*/
private String hardName;
private String hardType;
private List<String> hardTypeCodes;
}
@@ -0,0 +1,14 @@
package com.bsd.pjcloud.hard.api.vo.order;
import lombok.Data;
@Data
public class HardAppCreateThirdDoorOrderVo {
private Long authId;
/**
* 支付宝订单号
*/
private String alipayOrderStr;
}
@@ -27,6 +27,9 @@ public class HardCanteenProductTotalVo {
@Schema(description = "购买日期(年月日)")
private LocalDateTime createTime;
@Schema(description = "购买日期自定义格式")
private String createTimeStr;
@Schema(description = "用餐时间段(早中晚)")
private String hourType;
@@ -67,4 +67,16 @@ public class HardOrderCsVo implements BaseMchInterface, BaseHardInterface {
@Schema(description = "列号")
private Long lineNumber;
@Data
static public class Month {
@Schema(description = "日期")
private String day;
@Schema(description = "总盈利金额(元)")
private double totalProfitPrice;
@Schema(description = "总盈利次数")
private long totalProfitCount;
}
}
@@ -0,0 +1,55 @@
package com.bsd.pjcloud.hard.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 支付宝支付配置
*/
@Component
@ConfigurationProperties(prefix = "mini-ali-pay")
@Data
public class MiniAlipayConf {
/**
* 应用ID
*/
private String appId;
/**
* 商户号
*/
private String merchantId;
/**
* 商户账号
*/
private String merchantAccount;
/**
* 冻结金额
*/
private String freezeAmount;
/**
* 芝麻服务id
*/
private String zmServiceId;
/**
* 私钥
*/
private String privateKey;
/**
* 公钥
*/
private String publicKey;
/**
* 支付宝公钥
*/
private String alipayPublicKey;
}
@@ -4,6 +4,7 @@ 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.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.idempotent.annotation.Idempotent;
@@ -14,6 +15,7 @@ import com.bsd.pjcloud.hard.api.dto.*;
import com.bsd.pjcloud.hard.api.entity.HardAuthEntity;
import com.bsd.pjcloud.hard.api.vo.HardAuthVo;
import com.bsd.pjcloud.hard.api.vo.HardGetAuthAppVo;
import com.bsd.pjcloud.hard.api.vo.order.HardAppCreateThirdDoorOrderVo;
import com.bsd.pjcloud.hard.service.HardAuthService;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -48,17 +50,37 @@ public class HardAuthController {
public R<HardGetAuthAppVo> appGetAuthHardDoor(@Valid @RequestBody HardGetAuthAppDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setUserId(user.getId());
dto.setUserType(UserTypeEnum.valueOfByStatus(user.getUserType()));
return R.ok(hardAuthService.appGetAuthHardDoor(dto));
}
@Operation(summary = "app智能柜授权", description = "app智能柜授权")
@PostMapping("/app/auth-hard-door")
public R appAuthHardDoor(@Valid @RequestBody HardAuthAppDto dto) {
public R<Long> appAuthHardDoor(@Valid @RequestBody HardAuthAppDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setUserId(user.getId());
dto.setUserType(UserTypeEnum.TOB);
return R.ok(hardAuthService.appAuthHardDoor(dto));
}
@Operation(summary = "app创建第三方免密支付", description = "app创建第三方免密支付")
@PostMapping("/app/auth-create-third-door-order")
public R<HardAppCreateThirdDoorOrderVo> appCreateThirdDoorOrder(@Valid @RequestBody HardAuthAppDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setUserId(user.getId());
dto.setUserType(UserTypeEnum.TOC);
return R.ok(hardAuthService.appCreateThirdDoorOrder(dto));
}
@Operation(summary = "app创建第三方免密开门", description = "app创建第三方免密开门")
@PostMapping("/app/third-door-open")
public R<Long> appThirdDoorOpen(@Valid @RequestBody HardAppThirdOpenDoorDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setUserId(user.getId());
dto.setUserType(UserTypeEnum.TOC);
return R.ok(hardAuthService.appThirdDoorOpen(dto));
}
/* ************************************* end app end ************************************* */
@Operation(summary = "流程错误手动处理", description = "流程错误手动处理")
@@ -0,0 +1,132 @@
package com.bsd.pjcloud.hard.controller;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.hard.api.dto.HardThirdMiOrderDto;
import com.bsd.pjcloud.hard.api.dto.HardThirdMiPayDto;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.vo.HardThirdMiOrderVo;
import com.bsd.pjcloud.hard.service.HardThirdMiOrderService;
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;
import java.util.Objects;
/**
* 硬件商品免密订单
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/hard-third-mi-order")
@Tag(description = "hardThirdMiOrder", name = "硬件商品免密订单管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class HardThirdMiOrderController {
private final HardThirdMiOrderService hardThirdMiOrderService;
/**
* 刷新订单
*/
@Operation(summary = "刷新订单", description = "刷新订单")
@GetMapping("/refresh")
public R refresh(@RequestParam("id") Long id) {
hardThirdMiOrderService.refresh(id);
return R.ok();
}
/**
* 支付订单
*/
@Operation(summary = "支付订单", description = "支付订单")
@PostMapping("/admin-pay")
public R adminPay(@RequestBody HardThirdMiPayDto dto) {
hardThirdMiOrderService.adminPay(dto);
return R.ok();
}
/**
* 退款
*/
@Operation(summary = "退款", description = "退款")
@GetMapping("/refund")
public R refund(@RequestParam("id") Long id) {
hardThirdMiOrderService.refund(id);
return R.ok();
}
/**
* 分页查询
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('thirdmi_hardThirdMiOrder_view')")
public R<Page<HardThirdMiOrderVo>> getHardThirdMiOrderPage(@ParameterObject Page page, @ParameterObject HardThirdMiOrderDto dto) {
return R.ok(hardThirdMiOrderService.scopePageJoin(page, dto, null));
}
/**
* 通过id查询硬件商品免密订单
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('thirdmi_hardThirdMiOrder_view')")
public R getById(@PathVariable("id") Long id) {
return R.ok(hardThirdMiOrderService.getById(id));
}
/**
* 新增硬件商品免密订单
*/
@Operation(summary = "新增硬件商品免密订单", description = "新增硬件商品免密订单")
@SysLog("新增硬件商品免密订单")
@PostMapping
@PreAuthorize("@pms.hasPermission('thirdmi_hardThirdMiOrder_add')")
public R save(@RequestBody HardThirdMiOrderEntity hardThirdMiOrder) {
return R.ok(hardThirdMiOrderService.save(hardThirdMiOrder));
}
/**
* 修改硬件商品免密订单
*/
@Operation(summary = "修改硬件商品免密订单", description = "修改硬件商品免密订单")
@SysLog("修改硬件商品免密订单")
@PutMapping
@PreAuthorize("@pms.hasPermission('thirdmi_hardThirdMiOrder_edit')")
public R updateById(@RequestBody HardThirdMiOrderEntity hardThirdMiOrder) {
return R.ok(hardThirdMiOrderService.updateById(hardThirdMiOrder));
}
/**
* 通过id删除硬件商品免密订单
*/
@Operation(summary = "通过id删除硬件商品免密订单", description = "通过id删除硬件商品免密订单")
@SysLog("通过id删除硬件商品免密订单")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('thirdmi_hardThirdMiOrder_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(hardThirdMiOrderService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('thirdmi_hardThirdMiOrder_export')")
public List<HardThirdMiOrderEntity> export(HardThirdMiOrderEntity hardThirdMiOrder, Long[] ids) {
return hardThirdMiOrderService.list(Wrappers.lambdaQuery(hardThirdMiOrder).in(ArrayUtil.isNotEmpty(ids), HardThirdMiOrderEntity::getId, ids));
}
}
@@ -9,10 +9,7 @@ import com.bsd.pjcloud.hard.api.constant.HardProductNatureEnum;
import com.bsd.pjcloud.hard.api.constant.HardTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
import com.bsd.pjcloud.hard.api.dto.async.SyncOfflineReqVo;
import com.bsd.pjcloud.hard.api.dto.hard.HandCancelCodeDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardBindDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardCreateOrderDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardDoneHardQrCodeScanOrderDto;
import com.bsd.pjcloud.hard.api.dto.hard.*;
import com.bsd.pjcloud.hard.api.dto.order.HardChartLatitudeVo;
import com.bsd.pjcloud.hard.api.dto.order.HardCreateCarDto;
import com.bsd.pjcloud.hard.api.vo.HardInvoiceVo;
@@ -121,7 +118,7 @@ public class HardApiController {
@PostMapping("/cancel-code")
@Operation(summary = "核销二维码")
@Idempotent(expireTime = 10, info = "正在核销中,请勿重复操作")
@Idempotent(expireTime = 10, key = "'/hard-api/ad/cancel-code' + #dto.getOrderId() ", info = "正在核销中,请勿重复操作")
public R<Boolean> handCancelCode(@RequestBody HandCancelCodeDto dto) {
if (!ObjectUtil.isAllNotEmpty(dto.getOrderId(), dto.getHardwareId())) {
throw new RuntimeException("参数不正确");
@@ -129,6 +126,13 @@ public class HardApiController {
return R.ok(hardwareOrderService.handCancelCode(dto));
}
@PostMapping("/cancel-act-code")
@Operation(summary = "核销二维码")
@Idempotent(expireTime = 10, key = "'/hard-api/ad/cancel-act-code' + #dto.getActItemId() ", info = "正在核销中,请勿重复操作")
public R<Boolean> handCancelActCode(@Validated @RequestBody HandCancelActCodeDto dto) {
return R.ok(hardwareOrderService.handCancelActCode(dto));
}
@GetMapping("/generate-invoice")
@Operation(summary = "生成发票")
@Idempotent(expireTime = 10, info = "正在生成中,请勿重复操作")
@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
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;
@@ -21,11 +22,14 @@ import com.bsd.pjcloud.hard.service.HardCanteenTotalService;
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.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
@@ -82,7 +86,7 @@ public class HardCanteenTotalController {
return R.ok(canteenTotalService.productLikeTop(dto));
}
/* ************************************* start app start ************************************* */
/* ************************************* end app end ************************************* */
@Operation(summary = "根据部门 食堂菜品购买统计", description = "根据部门 食堂菜品购买统计")
@PostMapping("/proudct-total-by-dept")
public R<List<HardCanteenProductTotalVo>> productTotalByDept(@ParameterObject Page page, @RequestBody HardOrderDto dto) {
@@ -90,17 +94,48 @@ public class HardCanteenTotalController {
return R.ok(canteenTotalService.productTotalByDept(page, dto, dataScope));
}
@Operation(summary = "食堂菜品购买统计", description = "食堂菜品购买统计")
@Operation(summary = "食堂菜品购买统计(按天统计)", description = "食堂菜品购买统计(按天统计)")
@PostMapping("/proudct-total")
public R<Page<HardCanteenProductTotalVo>> productTotal(@ParameterObject Page page, @RequestBody HardOrderDto dto) {
DataScope dataScope = null;
return R.ok(canteenTotalService.productTotal(page, dto, dataScope));
}
@Operation(summary = "食堂菜品购买统计(按月统计)", description = "食堂菜品购买统计(按月统计)")
@PostMapping("/proudct-total-by-month")
public R<Page<HardCanteenProductTotalVo>> productTotalByMonth(@ParameterObject Page page, @RequestBody HardOrderDto dto) {
DataScope dataScope = null;
return R.ok(canteenTotalService.productTotalByMonth(page, dto, dataScope));
}
@Operation(summary = "菜品出售统计", description = "菜品出售统计")
@PostMapping("/proudct-query")
public R<Page<HardCarVo>> proudctQuery(@ParameterObject Page page, @RequestBody HardCarDto dto) {
return R.ok(canteenTotalService.proudctQuery(page, dto));
}
@Operation(summary = "食堂菜品购买统计导出(按天统计)", description = "食堂菜品购买统计导出(按天统计)")
@PostMapping("/proudct-total-export-by-day")
@SysLog("食堂菜品购买统计导出(按天统计)")
public void productTotalExportByDay(HttpServletResponse response, @RequestBody HardOrderDto dto) {
if (ObjectUtil.isEmpty(dto.getCreateTimeList())) {
throw new RuntimeException("请选择创建时间(天)");
}
// 导出最多只能导出一年
long days = Math.abs(ChronoUnit.DAYS.between(dto.getCreateTimeList()[0].toLocalDate(), dto.getCreateTimeList()[1].toLocalDate()));
if (days > 366) {
throw new RuntimeException("最多只能导出一年的数据");
}
canteenTotalService.productTotalExportByDay(response, dto);
}
@Operation(summary = "食堂菜品购买统计导出(按月统计)", description = "食堂菜品购买统计导出(按月统计)")
@PostMapping("/proudct-total-export-by-month")
@SysLog("食堂菜品购买统计导出(按月统计)")
public void productTotalExportByMonth(HttpServletResponse response, @RequestBody HardOrderDto dto) {
if (ObjectUtil.isEmpty(dto.getCreateTimeYearStr())) {
throw new RuntimeException("请选择创建时间(年)");
}
canteenTotalService.productTotalExportByMonth(response, dto);
}
}
@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
import com.bsd.pjcloud.canteen.constant.OrderTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.core.util.R;
@@ -125,6 +126,16 @@ public class HardOrderController {
return R.ok(hardwareOrderService.pagejoin(page, dto));
}
@Operation(summary = "app查询toc自提柜订单", description = "app查询toc自提柜订单")
@GetMapping("/app/toc-door-page-join")
public R appTocDoorPageJoin(@ParameterObject Page page, @ParameterObject HardOrderDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setUserId(user.getId());
dto.setIsFindCarList(true);
dto.setOrderTypeCodes(List.of(HardOrderTypeEnum.TOC_VISITOR.getType()));
return R.ok(hardwareOrderService.pagejoin(page, dto));
}
@Operation(summary = "app查询食堂订单列表", description = "app查询订单列表")
@GetMapping("/app/caneen-page-join")
public R appCaneenPageJoin(@ParameterObject Page page, @ParameterObject HardOrderDto dto) {
@@ -274,6 +285,29 @@ public class HardOrderController {
return R.ok(hardwareOrderService.scopePageList(page, dto, dataScope));
}
@Operation(summary = "分页查询未识别订单", description = "分页查询未识别订单")
@PostMapping("/no-recog/page-join")
@PreAuthorize("@pms.hasPermission('hard_hardwareOrderNoRecog_view')")
public R<Page<HardOrderVo>> noRecogPageJoin(@ParameterObject Page page, @RequestBody HardOrderDto dto) {
DataScope dataScope = DataScope.of().func(DataScopeFuncEnum.ALL);
dataScope.setScopeDeptName("merchant_dept_id");
PjcloudUser user = SecurityUtils.getUser();
CurrentUserHardTypeInfoDto hardTypeInfo = hardManagerService.getCurrentUserHardTypeInfo(user);
dto.setMchTypeCodes(hardTypeInfo.getHardTypeList());
// 查询商户和下面的子商户
List<Long> mchDtoIds = dto.getMchIds();
if (ObjectUtil.isNotEmpty(mchDtoIds) && mchDtoIds.size() == 1) {
Long mchId = mchDtoIds.get(0);
List<MchManageVo> mchList = mchService.getByParentId(mchId).getData();
if (ObjectUtil.isNotEmpty(mchList)) {
List<Long> mchIds = mchList.stream().map(MchManageVo::getId).toList();
mchDtoIds.addAll(mchIds);
dto.setMchIds(mchDtoIds);
}
}
return R.ok(hardwareOrderService.noRecogScopePageJoin(page, dto, dataScope));
}
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('hard_hardwareOrder_view')")
@@ -23,6 +23,7 @@ import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
import com.bsd.pjcloud.hard.api.dto.order.HardDeptTotalDto;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.vo.HardDoorFlowVo;
import com.bsd.pjcloud.hard.api.vo.order.*;
import com.bsd.pjcloud.hard.api.vo.order.excel.HardMchOrderExcelVo;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
@@ -142,6 +143,25 @@ public class HardOrderTotalController {
return R.ok(hardOrderTotalService.listCs(dto));
}
@PostMapping("/page-list-cs-by-month")
@Operation(summary = "商户交易记录(按商户、月)查询")
public R<Page<HardOrderCsVo>> pageListCsByMonth(@ParameterObject Page page, @RequestBody HardOrderDto dto) {
dto.setOrderStatusCodes(HardOrderStatusEnum.getPaySuccessCodes());
// 查询商户和下面的子商户
List<Long> mchDtoIds = new ArrayList<>();
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
List<MchManageVo> mchList = mchService.getByParentId(dto.getMerchantId()).getData();
if (ObjectUtil.isNotEmpty(mchList)) {
List<Long> mchIds = mchList.stream().map(MchManageVo::getId).toList();
mchDtoIds.add(dto.getMerchantId());
mchDtoIds.addAll(mchIds);
dto.setMerchantId(null);
dto.setMchIds(mchDtoIds);
}
}
return R.ok(hardOrderTotalService.pageListCsByMonth(page, dto));
}
@PostMapping("/page-list-payType")
@Operation(summary = "支付方式交易记录")
public R<List<HardOrderPayTypeVo>> pageListPayType(@RequestBody HardOrderDto dto) {
@@ -249,9 +269,7 @@ public class HardOrderTotalController {
if (ObjectUtil.isEmpty(mch)) throw new RuntimeException("商户不存在");
Long count = hardOrderMapper.count(dto, DataScope.of());
if (count > 5000) throw new RuntimeException("导出数据超出5000条,请缩小查询范围");
List<HardOrderVo> list = hardOrderService.scopeList(dto, DataScope.of());
List<HardMchOrderExcelVo> excelList = BeanUtils.toBean(list, HardMchOrderExcelVo.class);
if (count > 5 * 10000) throw new RuntimeException("导出数据超出100000条,请缩小查询范围");
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(ResourceUtil.getStream("file/商户交易流水导出.xlsx")).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
@@ -263,12 +281,23 @@ public class HardOrderTotalController {
map.put("endTime", LocalDateTimeUtil.format(dto.getPayTimeList()[1], DatePattern.NORM_DATETIME_PATTERN));
}
map.put("merchantName", mch.getName());
if (ObjectUtil.isNotEmpty(excelList)) {
BigDecimal totalPriceSum = BigDecimal.ZERO;
BigDecimal extraPriceSum = BigDecimal.ZERO;
BigDecimal payPriceSum = BigDecimal.ZERO;
BigDecimal refundPriceSum = BigDecimal.ZERO;
Long lineNumber = 1L;
// 统计
BigDecimal totalPriceSum = BigDecimal.ZERO;
BigDecimal extraPriceSum = BigDecimal.ZERO;
BigDecimal payPriceSum = BigDecimal.ZERO;
BigDecimal refundPriceSum = BigDecimal.ZERO;
// 列号
Long lineNumber = 1L;
// 分页相关
long currentPage = 1;
long pageSize = 1000;
while (true) {
Page<HardOrderVo> page = hardOrderService.scopePageList(new Page(currentPage, pageSize), dto, DataScope.of());
List<HardOrderVo> records = page.getRecords();
if (ObjectUtil.isEmpty(records)) break;
List<HardMchOrderExcelVo> excelList = BeanUtils.toBean(records, HardMchOrderExcelVo.class);
// 处理excel start
for (HardMchOrderExcelVo v : excelList) {
v.setLineNumber(lineNumber);
lineNumber++;
@@ -295,13 +324,17 @@ public class HardOrderTotalController {
}
}
}
map.put("totalPriceSum", totalPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
map.put("extraPriceSum", extraPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
map.put("payPriceSum", payPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
map.put("refundPriceSum", refundPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
excelWriter.fill(excelList, fillConfig, writeSheet);
// 处理excel end
if (page.getTotal() < pageSize) break;
currentPage++;
}
map.put("totalPriceSum", totalPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
map.put("extraPriceSum", extraPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
map.put("payPriceSum", payPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
map.put("refundPriceSum", refundPriceSum.divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).toString());
excelWriter.fill(map, writeSheet);
excelWriter.fill(excelList, fillConfig, writeSheet);
}
}
@@ -390,6 +423,27 @@ public class HardOrderTotalController {
}
}
@Operation(summary = "商户交易记录导出(按月)", description = "商户交易记录导出(按月)")
@PostMapping("/export-cs-by-month")
@SysLog("商户交易记录导出(按月)")
@PreAuthorize("@pms.hasPermission('hard_hardTotal_export_cs')")
public void exportCsByMonth(HttpServletResponse response, @RequestBody HardOrderDto dto) {
dto.setOrderStatusCodes(HardOrderStatusEnum.getPaySuccessCodes());
// 查询商户和下面的子商户
List<Long> mchDtoIds = new ArrayList<>();
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
List<MchManageVo> mchList = mchService.getByParentId(dto.getMerchantId()).getData();
if (ObjectUtil.isNotEmpty(mchList)) {
List<Long> mchIds = mchList.stream().map(MchManageVo::getId).toList();
mchDtoIds.add(dto.getMerchantId());
mchDtoIds.addAll(mchIds);
dto.setMerchantId(null);
dto.setMchIds(mchDtoIds);
}
}
hardOrderTotalService.exportCsByMonth(response, dto);
}
@Operation(summary = "支付方式交易记录", description = "支付方式交易记录")
@PostMapping("/export-payType")
@SysLog("支付方式交易记录")
@@ -0,0 +1,29 @@
package com.bsd.pjcloud.hard.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.hard.api.dto.HardThirdMiOrderDto;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.vo.HardThirdMiOrderVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface HardThirdMiOrderMapper extends PjcloudBaseMapper<HardThirdMiOrderEntity> {
default HardThirdMiOrderEntity getByAuthId(Long authId) {
return selectOne(new LambdaQueryWrapper<HardThirdMiOrderEntity>()
.eq(HardThirdMiOrderEntity::getAuthId, authId)
);
}
default HardThirdMiOrderEntity getByOrderId(Long orderId) {
return selectOne(new LambdaQueryWrapper<HardThirdMiOrderEntity>()
.eq(HardThirdMiOrderEntity::getOrderId, orderId)
);
}
Page<HardThirdMiOrderVo> scopePageJoin(Page page, @Param("dto") HardThirdMiOrderDto dto, DataScope dataScope);
}
@@ -34,6 +34,8 @@ public interface HardCarMapper extends PjcloudBaseMapper<HardCarEntity> {
Page<HardCanteenProductTotalVo> productTotal(Page page, @Param("dto") HardOrderDto dto, DataScope dataScope);
Page<HardCanteenProductTotalVo> productTotalByMonth(Page page, @Param("dto") HardOrderDto dto, DataScope dataScope);
Page<HardCarVo> proudctQuery(Page page, @Param("dto") HardCarDto dto);
List<HardCanteenProductTotalVo> listByDept(@Param("dto") HardOrderDto dto, DataScope dataScope);
@@ -10,6 +10,7 @@ import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderSumAndCountDto;
import com.bsd.pjcloud.hard.api.dto.order.HardSelectOrderMerchIdsDto;
import com.bsd.pjcloud.hard.api.dto.panel.PanelProductDto;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
@@ -108,6 +109,8 @@ public interface HardOrderMapper extends PjcloudBaseMapper<HardOrderEntity> {
return selectListByScope(commonWrapper(dto), DataScope.of());
}
List<Long> selectOrderMerchIds(@Param("dto") HardSelectOrderMerchIdsDto dto);
Page<HardOrderVo> scopePageList(Page page, @Param("dto") HardOrderDto dto, DataScope dataScope);
List<HardOrderVo> scopeList(@Param("dto") HardOrderDto dto, DataScope dataScope);
@@ -122,8 +125,12 @@ public interface HardOrderMapper extends PjcloudBaseMapper<HardOrderEntity> {
List<HardOrderCsVo> listRefundCs(@Param("dto") HardOrderDto refundDto, DataScope refundDataScope);
List<HardOrderCsVo> listRefundCsByMonth(@Param("dto") HardOrderDto refundDto, DataScope refundDataScope);
List<HardOrderCsVo> listCsByDay(@Param("dto") HardOrderDto totalDto);
Page<HardOrderCsVo> pageCsByMonth(Page page, @Param("dto") HardOrderDto totalDto, DataScope totalDataScope);
HardOrderCsVo listCsTotal(@Param("dto") HardOrderDto totalDto);
List<HardOrderPayTypeVo> listOrerPayType(@Param("dto") HardOrderDto dto);
@@ -3,13 +3,11 @@ package com.bsd.pjcloud.hard.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.dto.HardAuthAppDto;
import com.bsd.pjcloud.hard.api.dto.HardAuthDto;
import com.bsd.pjcloud.hard.api.dto.HardAuthErrorChangeDto;
import com.bsd.pjcloud.hard.api.dto.HardGetAuthAppDto;
import com.bsd.pjcloud.hard.api.dto.*;
import com.bsd.pjcloud.hard.api.entity.HardAuthEntity;
import com.bsd.pjcloud.hard.api.vo.HardAuthVo;
import com.bsd.pjcloud.hard.api.vo.HardGetAuthAppVo;
import com.bsd.pjcloud.hard.api.vo.order.HardAppCreateThirdDoorOrderVo;
import jakarta.validation.Valid;
public interface HardAuthService extends IService<HardAuthEntity> {
@@ -26,6 +24,16 @@ public interface HardAuthService extends IService<HardAuthEntity> {
*/
Long appAuthHardDoor(HardAuthAppDto dto);
/**
* app创建第三方免密支付
*/
HardAppCreateThirdDoorOrderVo appCreateThirdDoorOrder(@Valid HardAuthAppDto dto);
/**
* app创建第三方免密开门
*/
Long appThirdDoorOpen(@Valid HardAppThirdOpenDoorDto dto);
/**
* 判断当前用户信誉
*/
@@ -35,4 +43,5 @@ public interface HardAuthService extends IService<HardAuthEntity> {
* 流程错误手动处理
*/
void errorChange(HardAuthErrorChangeDto dto, Long userId);
}
@@ -13,6 +13,7 @@ import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByCanteenVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByClassifyVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
@@ -40,10 +41,15 @@ public interface HardCanteenTotalService {
List<HardCanteenProductTotalVo> productTotalByDept(Page page, HardOrderDto dto, DataScope dataScope);
/**
* 食堂菜品购买统计
* 食堂菜品购买统计(按天统计)
*/
Page<HardCanteenProductTotalVo> productTotal(Page page, HardOrderDto dto, DataScope dataScope);
/**
* 食堂菜品购买部门统计(按月统计)
*/
Page<HardCanteenProductTotalVo> productTotalByMonth(Page page, HardOrderDto dto, DataScope dataScope);
/**
* 菜品出售统计
*/
@@ -53,4 +59,14 @@ public interface HardCanteenTotalService {
* 食堂菜品购买部门统计
*/
List<HardCanteenProductTotalVo> listByDept(HardOrderDto dto, DataScope dataScope);
/**
* 食堂菜品购买统计导出(按天统计)
*/
void productTotalExportByDay(HttpServletResponse response, HardOrderDto dto);
/**
* 食堂菜品购买统计导出(按月统计)
*/
void productTotalExportByMonth(HttpServletResponse response, HardOrderDto dto);
}
@@ -2,6 +2,7 @@ package com.bsd.pjcloud.hard.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowDto;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowOpenDto;
@@ -40,7 +41,7 @@ public interface HardDoorFlowService extends IService<HardDoorFlowEntity> {
/**
* 购买开门
*/
void openDoorPay(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorDetail);
void openDoorPay(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorDetail, UserTypeEnum userType);
/**
* 上架开门
@@ -4,11 +4,13 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
import com.bsd.pjcloud.hard.api.dto.hard.HandCancelActCodeDto;
import com.bsd.pjcloud.hard.api.dto.hard.HandCancelCodeDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardCreateOrderDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardDoneHardQrCodeScanOrderDto;
@@ -38,6 +40,11 @@ public interface HardOrderService extends IService<HardOrderEntity> {
Page<HardOrderVo> scopePageList(Page page, HardOrderDto dto, DataScope dataScope);
/**
* 分页查询未识别订单
*/
Page<HardOrderVo> noRecogScopePageJoin(Page page, HardOrderDto dto, DataScope dataScope);
List<HardOrderVo> scopeList(HardOrderDto dto, DataScope dataScope);
HardOrderVo join(Long id);
@@ -85,7 +92,7 @@ public interface HardOrderService extends IService<HardOrderEntity> {
/**
* 创建智能柜订单
*/
Long createHardDoorOrder(Long userId, Long hardId);
Long createHardDoorOrder(Long userId, UserTypeEnum userType, Long hardId);
/**
* 结算智能柜订单
@@ -136,6 +143,11 @@ public interface HardOrderService extends IService<HardOrderEntity> {
*/
Boolean handCancelCode(HandCancelCodeDto dto);
/**
* 核销活动二维码
*/
Boolean handCancelActCode(HandCancelActCodeDto dto);
/**
* 创建订单后发送mq消息
*/
@@ -6,6 +6,7 @@ import com.bsd.pjcloud.hard.api.dto.order.HardChartLatitudeVo;
import com.bsd.pjcloud.hard.api.dto.order.HardDeptTotalDto;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.vo.order.*;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
@@ -21,6 +22,11 @@ public interface HardOrderTotalService {
*/
List<HardOrderCsVo> listCs(HardOrderDto dto);
/**
* 商户交易记录(按商户、月)查询
*/
Page<HardOrderCsVo> pageListCsByMonth(Page page, HardOrderDto dto);
/**
* 根据天查询每个商户的流水
*/
@@ -51,4 +57,8 @@ public interface HardOrderTotalService {
*/
HardChartLatitudeVo chartLatitude(Long merchantId);
/**
* 商户交易记录导出(按月)
*/
void exportCsByMonth(HttpServletResponse response, HardOrderDto dto);
}
@@ -0,0 +1,37 @@
package com.bsd.pjcloud.hard.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.dto.HardThirdMiOrderDto;
import com.bsd.pjcloud.hard.api.dto.HardThirdMiPayDto;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.vo.HardThirdMiOrderVo;
public interface HardThirdMiOrderService extends IService<HardThirdMiOrderEntity> {
/**
* 分页查询
*/
Page<HardThirdMiOrderVo> scopePageJoin(Page page, HardThirdMiOrderDto dto, DataScope dataScope);
/**
* 刷新订单
*/
HardThirdMiOrderEntity refresh(Long id);
/**
* 后台支付
*/
void adminPay(HardThirdMiPayDto dto);
/**
* 退款
*/
void refund(Long id);
/**
* 根据授权id查询授权订单
*/
HardThirdMiOrderEntity getByAuthId(Long authId);
}
@@ -0,0 +1,55 @@
package com.bsd.pjcloud.hard.service;
import com.alipay.api.response.*;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
public interface MiniAlipayService {
/**
* 获取智能柜小程序二维码
*/
String getDoorMiniQrCode(String hardDoorId, String cabinetNo);
/**
* 免密授权
*/
String miDynamicSign(Long userId, UserTypeEnum userType, Long authId);
/**
* 免密授权(需要押金)
*/
ZhimaCreditPayafteruseCreditbizorderCreateResponse miDynamicCreate(Long userId, UserTypeEnum userType, Long authId);
/**
* 查询免密授权
*/
ZhimaCreditPayafteruseCreditagreementQueryResponse miDynamicQueySign(Long authId);
/**
* 免密服务下单
*/
ZhimaCreditPayafteruseCreditbizorderOrderResponse miDynamicOrder(Long authId, Long orderId, Long flowId);
/**
* 创建支付宝免密订单
*/
AlipayTradeCreateResponse miCreateOrder(String openId, Long authId, Long userId, UserTypeEnum userType);
/**
* 查询支付宝免密订单
*/
ZhimaCreditPayafteruseCreditbizorderQueryResponse miQueryOrder(String alipayOrderNo, Long authId);
/**
* 支付宝免密扣款
*/
boolean miPay(HardThirdMiOrderEntity thirdOrder, int totalPrice);
/**
* 支付宝免密(取消/退款)
*/
AlipayTradeRefundResponse miCancelOrRefund(HardThirdMiOrderEntity thirdOrder);
}
@@ -1,34 +1,40 @@
package com.bsd.pjcloud.hard.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.alipay.api.response.ZhimaCreditPayafteruseCreditbizorderCreateResponse;
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.app.api.dto.AppUserInfo;
import com.bsd.pjcloud.app.api.entity.AppUser;
import com.bsd.pjcloud.app.api.feign.RemoteAppUserService;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.constant.HardAuthTypeEnum;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiTypeEnum;
import com.bsd.pjcloud.hard.api.constant.flow.HardDoorFlowBizEnum;
import com.bsd.pjcloud.hard.api.constant.HardDoorOpenTypeEnum;
import com.bsd.pjcloud.hard.api.dto.*;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
import com.bsd.pjcloud.hard.api.entity.HardAuthEntity;
import com.bsd.pjcloud.hard.api.entity.HardDoorFlowEntity;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.utils.HardUtil;
import com.bsd.pjcloud.hard.api.vo.HardAuthVo;
import com.bsd.pjcloud.hard.api.vo.HardGetAuthAppVo;
import com.bsd.pjcloud.hard.api.vo.manager.HardDoorManagerVo;
import com.bsd.pjcloud.hard.api.vo.order.HardAppCreateThirdDoorOrderVo;
import com.bsd.pjcloud.hard.mapper.HardAuthMapper;
import com.bsd.pjcloud.hard.mapper.manager.HardManagerMapper;
import com.bsd.pjcloud.hard.service.HardAuthService;
import com.bsd.pjcloud.hard.service.HardDoorFlowService;
import com.bsd.pjcloud.hard.service.HardDoorManagerService;
import com.bsd.pjcloud.hard.service.HardOrderService;
import com.bsd.pjcloud.hard.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -51,10 +57,13 @@ public class HardAuthServiceImpl extends ServiceImpl<HardAuthMapper, HardAuthEnt
private final HardDoorManagerService hardDoorManagerService;
private final HardDoorFlowService hardDoorFlowService;
private final HardOrderService hardOrderService;
private final MiniAlipayService miniAlipayService;
private final HardThirdMiOrderService hardThirdMiOrderService;
private final HardManagerMapper hardManagerMapper;
private final RemoteUserService remoteUserService;
private final RemoteAppUserService remoteAppUserService;
@Override
public Page<HardAuthVo> scopePageJoin(Page page, HardAuthDto dto, DataScope dataScope) {
@@ -73,11 +82,15 @@ public class HardAuthServiceImpl extends ServiceImpl<HardAuthMapper, HardAuthEnt
if (ObjectUtil.isEmpty(hardDoorDetail)) {
throw new RuntimeException("获取智能柜授权信息错误");
}
String authType = HardAuthTypeEnum.HARD_DDOR_AUTH.getType();
if (ObjectUtil.equals(UserTypeEnum.TOC, dto.getUserType())) {
authType = HardAuthTypeEnum.HARD_DDOR_TOC_AUTH.getType();
}
HardAuthEntity insetObj = HardAuthEntity.builder()
.userId(dto.getUserId())
.hardId(hardDoorDetail.getHardId())
.cabinetNo(dto.getCabinetNo())
.authType(HardAuthTypeEnum.HARD_DDOR_AUTH.getType())
.authType(authType)
.authStatus(YesNoEnum.NO.getCode())
.isDone(YesNoEnum.NO.getCode())
.build();
@@ -99,7 +112,7 @@ public class HardAuthServiceImpl extends ServiceImpl<HardAuthMapper, HardAuthEnt
if (ObjectUtil.isEmpty(authEntity)) throw new RuntimeException("授权信息不存在");
// 查询设备信息
HardDoorManagerVo hardDoorDetail = hardDoorManagerService.getByHardId(authEntity.getHardId());
if (ObjectUtil.isEmpty(hardDoorDetail)) throw new RuntimeException("授权信息不存在");
if (ObjectUtil.isEmpty(hardDoorDetail)) throw new RuntimeException("设备信息不存在");
HardAuthEntity updateObj = HardAuthEntity.builder().id(dto.getAuthId()).authStatus(dto.getAuthStatus()).authTime(LocalDateTime.now()).build();
baseMapper.updateById(updateObj);
if (ObjectUtil.equals(dto.getAuthStatus(), YesNoEnum.YES.getCode())) {
@@ -111,11 +124,82 @@ public class HardAuthServiceImpl extends ServiceImpl<HardAuthMapper, HardAuthEnt
openDoorDto.setOpenType(HardDoorOpenTypeEnum.RECORD_VIDEO);
openDoorDto.setUserId(dto.getUserId());
openDoorDto.setAuthId(dto.getAuthId());
hardDoorFlowService.openDoorPay(openDoorDto, hardDoorDetail);
hardDoorFlowService.openDoorPay(openDoorDto, hardDoorDetail, dto.getUserType());
}
return dto.getAuthId();
}
/**
* app创建第三方免密支付
*/
@Override
public HardAppCreateThirdDoorOrderVo appCreateThirdDoorOrder(HardAuthAppDto dto) {
// 查询授权信息
HardAuthEntity authEntity = baseMapper.selectById(dto.getAuthId());
if (ObjectUtil.isEmpty(authEntity)) throw new RuntimeException("授权信息不存在");
// 查询设备信息
HardDoorManagerVo hardDoorDetail = hardDoorManagerService.getByHardId(authEntity.getHardId());
if (ObjectUtil.isEmpty(hardDoorDetail)) throw new RuntimeException("设备信息不存在");
// 查询第三方用户信息
AppUserInfo appUserInfo = remoteAppUserService.infoByUserId(dto.getUserId()).getData();
if (ObjectUtil.isEmpty(appUserInfo)) throw new RuntimeException("第三方用户信息不存在");
AppUser appUser = appUserInfo.getAppUser();
if (ObjectUtil.equals(dto.getAuthStatus(), YesNoEnum.NO.getCode())) {
throw new RuntimeException("请先授权");
}
HardAppCreateThirdDoorOrderVo res = new HardAppCreateThirdDoorOrderVo();
AlipayTradeCreateResponse alipayRes = miniAlipayService.miCreateOrder(appUser.getOpenid(), authEntity.getId(), dto.getUserId(), dto.getUserType());
if (ObjectUtil.isEmpty(alipayRes)) {
throw new RuntimeException("创建支付宝免密订单失败");
}
res.setAlipayOrderStr(alipayRes.getTradeNo());
return res;
}
/**
* app创建第三方免密开门
*/
@Override
public Long appThirdDoorOpen(HardAppThirdOpenDoorDto dto) {
// 查询授权信息
HardAuthEntity authEntity = baseMapper.selectById(dto.getAuthId());
if (ObjectUtil.isEmpty(authEntity)) throw new RuntimeException("授权信息不存在");
// 查询设备信息
HardDoorManagerVo hardDoorDetail = hardDoorManagerService.getByHardId(authEntity.getHardId());
if (ObjectUtil.isEmpty(hardDoorDetail)) throw new RuntimeException("设备信息不存在");
HardThirdMiOrderEntity thirdMiOrder = hardThirdMiOrderService.getByAuthId(dto.getAuthId());
if (ObjectUtil.isEmpty(thirdMiOrder)) throw new RuntimeException("第三方免密订单不存在");
if (ObjectUtil.equals(dto.getUserType(), UserTypeEnum.TOC.getStatus())) {
// 微信免密支付
if (ObjectUtil.equals(thirdMiOrder.getBizType(), HardThirdMiTypeEnum.MI_WECHAT.getType())) {
}
// 支付宝-芝麻先享
if (ObjectUtil.equals(thirdMiOrder.getBizType(), HardThirdMiTypeEnum.MI_ALIPAY.getType())) {
}
}
HardAuthEntity updateObj = HardAuthEntity.builder().id(dto.getAuthId()).authStatus(YesNoEnum.YES.getCode()).authTime(LocalDateTime.now()).build();
baseMapper.updateById(updateObj);
// 开门
HardDoorFlowOpenDto openDoorDto = new HardDoorFlowOpenDto();
openDoorDto.setHardDoorId(hardDoorDetail.getId());
openDoorDto.setCabinetNo(authEntity.getCabinetNo());
openDoorDto.setFlowType(HardDoorFlowBizEnum.PAY_OPEN);
openDoorDto.setOpenType(HardDoorOpenTypeEnum.RECORD_VIDEO);
openDoorDto.setUserId(dto.getUserId());
openDoorDto.setAuthId(dto.getAuthId());
hardDoorFlowService.openDoorPay(openDoorDto, hardDoorDetail, dto.getUserType());
return updateObj.getId();
}
/**
* 判断当前用户信誉
*/
@@ -5,16 +5,20 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.response.ZhimaCreditPayafteruseCreditbizorderOrderResponse;
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.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiStatusEnum;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiTypeEnum;
import com.bsd.pjcloud.hard.api.constant.flow.HardDoorFlowBizEnum;
import com.bsd.pjcloud.hard.api.constant.flow.HardDoorFlowEnum;
import com.bsd.pjcloud.hard.api.dto.HardDoorFlowDto;
@@ -22,6 +26,7 @@ import com.bsd.pjcloud.hard.api.dto.HardDoorFlowOpenDto;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
import com.bsd.pjcloud.hard.api.entity.HardAuthEntity;
import com.bsd.pjcloud.hard.api.entity.HardDoorFlowEntity;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardDoorManagerEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
@@ -33,6 +38,7 @@ import com.bsd.pjcloud.hard.api.vo.spu.HardSpuJoinVo;
import java.time.temporal.ChronoUnit;
import com.bsd.pjcloud.hard.mapper.HardDoorFlowMapper;
import com.bsd.pjcloud.hard.mapper.HardThirdMiOrderMapper;
import com.bsd.pjcloud.hard.mapper.manager.HardManagerMapper;
import com.bsd.pjcloud.hard.service.*;
import com.bsd.pjcloud.thirdparty.api.feign.RemoterThirdDoorApiService;
@@ -73,8 +79,11 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
private final HardOrderService hardOrderService;
@Lazy
private final HardAuthService hardAuthService;
private final HardThirdMiOrderService hardThirdMiOrderService;
private final MiniAlipayService miniAlipayService;
private final HardManagerMapper hardManagerMapper;
private final HardThirdMiOrderMapper hardThirdMiOrderMapper;
private final RemoterThirdDoorApiService thirdDoorApiService;
private final RemoterThirdKsService thirdKsService;
@@ -125,8 +134,8 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
* 开门
*/
@Transactional(rollbackFor = Exception.class)
public Long openDoor(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorVo) {
HardDoorFlowEntity saveObj = HardDoorFlowEntity.builder().flowStatus(HardDoorFlowEnum.FLOW_AUTH.getType()).userId(dto.getUserId()).bizType(dto.getFlowType().getType()).isOpen(YesNoEnum.NO.getCode()).build();
public Long openDoor(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorVo, UserTypeEnum userType) {
HardDoorFlowEntity saveObj = HardDoorFlowEntity.builder().flowStatus(HardDoorFlowEnum.FLOW_AUTH.getType()).userId(dto.getUserId()).userType(userType.getStatus()).bizType(dto.getFlowType().getType()).isOpen(YesNoEnum.NO.getCode()).build();
baseMapper.insert(saveObj);
hardDoorManagerService.refresh(hardDoorVo.getDeviceCode());
// 校验设备和货柜编号
@@ -161,7 +170,7 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
public void openDoorAccess(HardDoorFlowOpenDto dto) {
// 查询智能柜
HardDoorManagerVo doorDetail = hardDoorManagerService.checkDeviceAndCabinet(dto.getHardDoorId(), dto.getCabinetNo());
getSelf().openDoor(dto, doorDetail);
getSelf().openDoor(dto, doorDetail, UserTypeEnum.TOB);
}
/**
@@ -188,14 +197,16 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void openDoorPay(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorDetail) {
public void openDoorPay(HardDoorFlowOpenDto dto, HardDoorManagerVo hardDoorDetail, UserTypeEnum userType) {
if (ObjectUtil.isNotEmpty(dto.getHardDoorFlowId()) || ObjectUtil.isEmpty(hardDoorDetail)) {
return;
}
// 查看用户消费钱包余额
String walletErrorMsg = remoteWalletService.innserIsUseDoor(dto.getUserId()).getData();
if (ObjectUtil.isNotEmpty(walletErrorMsg)) {
throw new RuntimeException(walletErrorMsg);
if (ObjectUtil.equals(userType, UserTypeEnum.TOB)) {
// 查看用户消费钱包余额
String walletErrorMsg = remoteWalletService.innserIsUseDoor(dto.getUserId()).getData();
if (ObjectUtil.isNotEmpty(walletErrorMsg)) {
throw new RuntimeException(walletErrorMsg);
}
}
// 查看用户信誉
boolean userCredit = hardAuthService.judgeUserCredit(dto.getUserId());
@@ -213,7 +224,7 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
// 查询货柜是否配置spu信息
List<HardSpuJoinVo> spuList = hardSpuJoinService.getSpuList(hardDoorDetail.getId(), dto.getCabinetNo());
if (ObjectUtil.isEmpty(spuList) || spuList.isEmpty()) throw new RuntimeException("货柜商品信息为空,请上架");
getSelf().openDoor(dto, hardDoorDetail);
getSelf().openDoor(dto, hardDoorDetail, userType);
}
/**
@@ -223,13 +234,14 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
public Long openDoorRepertory(HardDoorFlowOpenDto dto) {
// 查询智能柜
HardDoorManagerVo doorDetail = hardDoorManagerService.checkDeviceAndCabinet(dto.getHardDoorId(), dto.getCabinetNo());
return getSelf().openDoor(dto, doorDetail);
return getSelf().openDoor(dto, doorDetail, UserTypeEnum.TOB);
}
/**
* 处理开门回调
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void disposeLocakCallback(DoorOpenCallbackDto dto) {
if (ObjectUtil.isEmpty(dto.getType()) || ObjectUtil.equals(dto.getResultCode(), "FAIL")) return;
// 查询流程
@@ -240,8 +252,35 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
// 如果是购买的话
if (ObjectUtil.equals(flowDetail.getBizType(), HardDoorFlowBizEnum.PAY_OPEN.getType())) {
// 创建订单
Long orderId = hardOrderService.createHardDoorOrder(flowDetail.getUserId(), flowDetail.getHardId());
UserTypeEnum userType = UserTypeEnum.TOB;
if (ObjectUtil.isNotEmpty(flowDetail.getUserType())) {
userType = UserTypeEnum.valueOfByStatus(flowDetail.getUserType());
}
Long orderId = hardOrderService.createHardDoorOrder(flowDetail.getUserId(), userType, flowDetail.getHardId());
updateObj.setOrderId(orderId);
if (ObjectUtil.equals(flowDetail.getUserType(), UserTypeEnum.TOC.getStatus())) {
// 更新`hard_third_mi_order`表
HardThirdMiOrderEntity thirdOrder = hardThirdMiOrderService.getByAuthId(flowDetail.getAuthId());
if (ObjectUtil.isEmpty(thirdOrder)) {
log.error("|{}|disposeLocakCallback创建第三方免密支付错误,原因:未查询到第三方免密支付记录authId|{}|", TAG, flowDetail.getAuthId());
} else {
HardThirdMiOrderEntity updateMiOrderObj = new HardThirdMiOrderEntity();
updateMiOrderObj.setId(thirdOrder.getId());
updateMiOrderObj.setOrderId(orderId);
updateMiOrderObj.setFlowId(flowDetail.getId());
updateMiOrderObj.setOutOrderNo(String.valueOf(orderId));
updateMiOrderObj.setHardId(flowDetail.getHardId());
hardThirdMiOrderMapper.updateById(updateMiOrderObj);
// 微信免密支付
if (ObjectUtil.equals(thirdOrder.getBizType(), HardThirdMiTypeEnum.MI_WECHAT.getType())) {
}
// 支付宝-芝麻先享
if (ObjectUtil.equals(thirdOrder.getBizType(), HardThirdMiTypeEnum.MI_ALIPAY.getType())) {
}
}
}
}
baseMapper.updateById(updateObj);
}
@@ -0,0 +1,211 @@
package com.bsd.pjcloud.hard.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.api.response.ZhimaCreditPayafteruseCreditbizorderQueryResponse;
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.vo.UserVO;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiStatusEnum;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiTypeEnum;
import com.bsd.pjcloud.hard.api.dto.HardThirdMiOrderDto;
import com.bsd.pjcloud.hard.api.dto.HardThirdMiPayDto;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.utils.HardUtil;
import com.bsd.pjcloud.hard.api.vo.HardThirdMiOrderVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
import com.bsd.pjcloud.hard.mapper.HardThirdMiOrderMapper;
import com.bsd.pjcloud.hard.mapper.manager.HardManagerMapper;
import com.bsd.pjcloud.hard.service.HardThirdMiOrderService;
import com.bsd.pjcloud.hard.service.MiniAlipayService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* 硬件商品免密订单
*/
@Service
@AllArgsConstructor
public class HardThirdMiOrderServiceImpl extends ServiceImpl<HardThirdMiOrderMapper, HardThirdMiOrderEntity> implements HardThirdMiOrderService {
private final HardManagerMapper hardManagerMapper;
private final MiniAlipayService miniAlipayService;
private final RemoteUserService userService;
/**
* 分页查询
*/
@Override
public Page<HardThirdMiOrderVo> scopePageJoin(Page page, HardThirdMiOrderDto dto, DataScope dataScope) {
Page<HardThirdMiOrderVo> pageList = baseMapper.scopePageJoin(page, dto, dataScope);
disposeList(pageList.getRecords());
return pageList;
}
/**
* 刷新订单
*/
@Override
public HardThirdMiOrderEntity refresh(Long id) {
HardThirdMiOrderEntity order = baseMapper.selectById(id);
if (ObjectUtil.isEmpty(order)) {
throw new RuntimeException("订单不存在");
}
// 微信免密支付
if (ObjectUtil.equals(order.getBizType(), HardThirdMiTypeEnum.MI_WECHAT.getType())) {
return null;
}
// 支付宝-芝麻先享
if (ObjectUtil.equals(order.getBizType(), HardThirdMiTypeEnum.MI_ALIPAY.getType())) {
ZhimaCreditPayafteruseCreditbizorderQueryResponse res = miniAlipayService.miQueryOrder(null, order.getAuthId());
if (ObjectUtil.isEmpty(res)) {
throw new RuntimeException("支付宝-芝麻先享,未查询到此订单");
}
HardThirdMiOrderEntity updateObj = new HardThirdMiOrderEntity();
updateObj.setId(order.getId());
// 押金
updateObj.setDepositPrice(new BigDecimal(res.getTotalAmount()).multiply(BigDecimal.valueOf(100)).intValue());
// 扣款金额
if (ObjectUtil.isNotEmpty(res.getTotalCreditPayAmount())) {
updateObj.setPayPrice(new BigDecimal(res.getTotalCreditPayAmount()).multiply(BigDecimal.valueOf(100)).intValue());
}
// 订单状态
if (ObjectUtil.isNotEmpty(res.getOrderStatus())) {
String orderStatus = res.getOrderStatus();
switch (orderStatus) {
// 下单状态
case "INIT":
updateObj.setOrderStatus(HardThirdMiStatusEnum.CREATE_ORDER.getType());
break;
// 订单取消或者交易全额退款
case "TRADE_CLOSED":
updateObj.setOrderStatus(HardThirdMiStatusEnum.REFUND.getType());
break;
// 扣款成功状态
case "TRADE_FINISHED":
updateObj.setOrderStatus(HardThirdMiStatusEnum.PAY_SUCCESS.getType());
break;
}
}
baseMapper.updateById(updateObj);
return baseMapper.selectById(order.getId());
}
return null;
}
/**
* 后台支付
*/
@Override
public void adminPay(HardThirdMiPayDto dto) {
HardThirdMiOrderEntity order = baseMapper.selectById(dto.getId());
if (ObjectUtil.isEmpty(order)) {
throw new RuntimeException("订单不存在");
}
// 微信免密支付
if (ObjectUtil.equals(order.getBizType(), HardThirdMiTypeEnum.MI_WECHAT.getType())) {
refresh(dto.getId());
return;
}
// 支付宝-芝麻先享
if (ObjectUtil.equals(order.getBizType(), HardThirdMiTypeEnum.MI_ALIPAY.getType())) {
if (ObjectUtil.isEmpty(order.getOrderId())) {
throw new RuntimeException("支付宝-芝麻先享,此订单未创建");
}
miniAlipayService.miPay(order, 10);
refresh(dto.getId());
return;
}
}
/**
* 退款
*/
@Override
public void refund(Long id) {
HardThirdMiOrderEntity order = baseMapper.selectById(id);
if (ObjectUtil.isEmpty(order) || ObjectUtil.isNotEmpty(order.getOrderId())) {
throw new RuntimeException("订单不存在");
}
order = refresh(id);
// 微信免密支付
if (ObjectUtil.equals(order.getBizType(), HardThirdMiTypeEnum.MI_WECHAT.getType())) {
return;
}
// 支付宝-芝麻先享
if (ObjectUtil.equals(order.getBizType(), HardThirdMiTypeEnum.MI_ALIPAY.getType())) {
if (ObjectUtil.equals(order.getOrderStatus(), HardThirdMiStatusEnum.REFUND.getType())) {
throw new RuntimeException("支付宝-芝麻先享,此订单已退款");
}
if (ObjectUtil.notEqual(order.getOrderStatus(), HardThirdMiStatusEnum.PAY_SUCCESS.getType())) {
throw new RuntimeException("支付宝-芝麻先享,此订单未支付");
}
miniAlipayService.miCancelOrRefund(order);
}
}
/**
* 根据授权id查询授权订单
*/
@Override
public HardThirdMiOrderEntity getByAuthId(Long authId) {
return baseMapper.selectOne(new LambdaQueryWrapper<HardThirdMiOrderEntity>()
.eq(HardThirdMiOrderEntity::getAuthId, authId)
);
}
private void disposeList(List<HardThirdMiOrderVo> list) {
if (ObjectUtil.isEmpty(list)) return;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 用户部门
CompletableFuture<Void> userFuture = CompletableFuture.runAsync(() -> {
RequestContextHolder.setRequestAttributes(requestAttributes);
List<Long> userIds = list.stream().map(HardThirdMiOrderVo::getUserId).filter(ObjectUtil::isNotEmpty).distinct().toList();
if (ObjectUtil.isNotEmpty(userIds)) {
List<UserVO> userList = userService.getUserDeptByIds(userIds).getData();
if (ObjectUtil.isNotEmpty(userList)) {
Map<Long, UserVO> map = CollectionUtils.convertMap(userList, UserVO::getUserId);
for (HardThirdMiOrderVo item : list) {
UserVO userVO = map.get(item.getUserId());
if (ObjectUtil.isEmpty(userVO)) continue;
item.setUsername(userVO.getName());
item.setUserMobile(userVO.getPhone());
item.setUserAvatar(userVO.getAvatar());
}
}
}
});
// 设备
CompletableFuture<Void> deviceFuture = CompletableFuture.runAsync(() -> {
RequestContextHolder.setRequestAttributes(requestAttributes);
List<Long> hardIds = list.stream().map(HardThirdMiOrderVo::getHardId).filter(ObjectUtil::isNotEmpty).distinct().toList();
if (ObjectUtil.isNotEmpty(hardIds)) {
HardManagerDto hardManagerDto = new HardManagerDto();
hardManagerDto.setIds(hardIds);
List<HardManagerEntity> hardList = hardManagerMapper.list(hardManagerDto);
if (ObjectUtil.isNotEmpty(hardList)) {
HardUtil.convertHardList(list, CollectionUtils.convertMap(hardList, HardManagerEntity::getId));
}
}
});
CompletableFuture.allOf(userFuture, deviceFuture).join();
}
}
@@ -0,0 +1,457 @@
package com.bsd.pjcloud.hard.service.impl.ali;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiStatusEnum;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiTypeEnum;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.config.MiniAlipayConf;
import com.bsd.pjcloud.hard.mapper.HardThirdMiOrderMapper;
import com.bsd.pjcloud.hard.service.HardThirdMiOrderService;
import com.bsd.pjcloud.hard.service.MiniAlipayService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
/**
* 支付宝小程序支付
*/
@Service
@AllArgsConstructor
@Slf4j
public class MiniAlipayServiceImpl implements MiniAlipayService {
private final HardThirdMiOrderMapper hardThirdMiOrderMapper;
private final MiniAlipayConf conf;
static private AlipayClient client = null;
private void initClient() {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(conf.getAppId());
alipayConfig.setPrivateKey(conf.getPrivateKey());
alipayConfig.setFormat("json");
alipayConfig.setCharset("UTF-8");
alipayConfig.setAlipayPublicKey(conf.getAlipayPublicKey());
alipayConfig.setSignType("RSA2");
try {
MiniAlipayServiceImpl.client = new DefaultAlipayClient(alipayConfig);
} catch (Exception e) {
log.error("初始化支付宝客户端异常", e);
}
}
private AlipayClient getClient() {
if (ObjectUtil.isEmpty(MiniAlipayServiceImpl.client)) initClient();
return MiniAlipayServiceImpl.client;
}
/**
* 获取智能柜小程序二维码
*/
@Override
public String getDoorMiniQrCode(String hardDoorId, String cabinetNo) {
AlipayOpenAppQrcodeCreateRequest request = new AlipayOpenAppQrcodeCreateRequest();
AlipayOpenAppQrcodeCreateModel model = new AlipayOpenAppQrcodeCreateModel();
model.setUrlParam("pages/tabbar/login");
model.setQueryParam(String.format("action=scan&path=%s&hardDoorId=%s&cabinetNo=%s", "pages/tabbar/login", hardDoorId, cabinetNo));
model.setDescribe("支付宝智能柜二维码");
request.setBizModel(model);
try {
AlipayOpenAppQrcodeCreateResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|获取小程序二维码|失败,json|{}", response.getBody());
return null;
}
return response.getQrCodeUrlCircleBlue();
} catch (Exception e) {
e.printStackTrace();
log.error("|获取小程序二维码|异常", e);
return null;
}
}
/**
* 免密授权
*/
@Override
public String miDynamicSign(Long userId, UserTypeEnum userType, Long authId) {
HardThirdMiOrderEntity thirdOrder = new HardThirdMiOrderEntity();
thirdOrder.setBizType(HardThirdMiTypeEnum.MI_ALIPAY.getType());
thirdOrder.setAuthId(authId);
thirdOrder.setUserId(userId);
thirdOrder.setUserType(userType.getStatus());
thirdOrder.setCreateOrderTime(LocalDateTime.now());
thirdOrder.setOrderStatus(HardThirdMiStatusEnum.CREATE_ORDER.getType());
ZhimaCreditPayafteruseCreditagreementSignRequest request = new ZhimaCreditPayafteruseCreditagreementSignRequest();
ZhimaCreditPayafteruseCreditagreementSignModel model = new ZhimaCreditPayafteruseCreditagreementSignModel();
// 设置芝麻信用服务ID
model.setZmServiceId(conf.getZmServiceId());
// 设置芝麻外部类目
model.setCategoryId("credit_pay_after_use");
model.setOutAgreementNo(String.valueOf(authId));
request.setBizModel(model);
try {
ZhimaCreditPayafteruseCreditagreementSignResponse response = getClient().sdkExecute(request);
if (!response.isSuccess()) {
log.error("|免密授权|失败,json|{}", response.getBody());
return null;
}
return response.getBody();
} catch (Exception e) {
e.printStackTrace();
log.error("|免密授权|异常", e);
return null;
} finally {
hardThirdMiOrderMapper.insert(thirdOrder);
}
}
/**
* 免密授权(需要押金)
*/
@Override
public ZhimaCreditPayafteruseCreditbizorderCreateResponse miDynamicCreate(Long userId, UserTypeEnum userType, Long authId) {
int depositPricePrice = 300;
HardThirdMiOrderEntity thirdOrder = new HardThirdMiOrderEntity();
thirdOrder.setBizType(HardThirdMiTypeEnum.MI_ALIPAY.getType());
thirdOrder.setAuthId(authId);
thirdOrder.setUserId(userId);
thirdOrder.setDepositPrice(depositPricePrice);
thirdOrder.setUserType(userType.getStatus());
thirdOrder.setCreateOrderTime(LocalDateTime.now());
thirdOrder.setOrderStatus(HardThirdMiStatusEnum.CREATE_ORDER.getType());
ZhimaCreditPayafteruseCreditbizorderCreateRequest request = new ZhimaCreditPayafteruseCreditbizorderCreateRequest();
ZhimaCreditPayafteruseCreditbizorderCreateModel model = new ZhimaCreditPayafteruseCreditbizorderCreateModel();
model.setOutOrderNo(String.valueOf(authId));
model.setAmountType("RISK_AMOUNT");
model.setZmServiceId(conf.getZmServiceId());
model.setCategoryId("credit_pay_after_use");
model.setOrderAmount(new BigDecimal(depositPricePrice).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString());
model.setProductCode("CREDIT_PAY_AFTER_USE");
model.setSubject("浦江智能柜芝麻先享");
model.setBody("浦江智能柜芝麻先享");
request.setBizModel(model);
System.out.println(JSONUtil.toJsonStr(model));
try {
ZhimaCreditPayafteruseCreditbizorderCreateResponse response = getClient().sdkExecute(request);
if (!response.isSuccess()) {
log.error("|免密授权(需要押金)|失败,json|{}", response.getBody());
return null;
}
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|免密授权(需要押金)|异常", e);
return null;
} finally {
hardThirdMiOrderMapper.insert(thirdOrder);
}
}
/**
* 查询面密授权
*/
@Override
public ZhimaCreditPayafteruseCreditagreementQueryResponse miDynamicQueySign(Long authId) {
HardThirdMiOrderEntity thirdMiOrder = hardThirdMiOrderMapper.getByAuthId(authId);
if (ObjectUtil.isEmpty(thirdMiOrder)) {
log.error("|查询面密授权|订单不存在,authId|{}", authId);
return null;
}
HardThirdMiOrderEntity updateObj = new HardThirdMiOrderEntity();
updateObj.setId(thirdMiOrder.getId());
ZhimaCreditPayafteruseCreditagreementQueryRequest request = new ZhimaCreditPayafteruseCreditagreementQueryRequest();
ZhimaCreditPayafteruseCreditagreementQueryModel model = new ZhimaCreditPayafteruseCreditagreementQueryModel();
model.setOutAgreementNo(String.valueOf(authId));
request.setBizModel(model);
try {
ZhimaCreditPayafteruseCreditagreementQueryResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|查询面密授权|失败,json|{}", response.getBody());
return null;
}
updateObj.setOrgSignJson(JSONUtil.toJsonStr(response));
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|查询面密授权|异常", e);
return null;
} finally {
if (ObjectUtil.isNotEmpty(updateObj.getOrgSignJson())) {
hardThirdMiOrderMapper.updateById(updateObj);
}
}
}
/**
* 免密服务下单
*/
@Override
public ZhimaCreditPayafteruseCreditbizorderOrderResponse miDynamicOrder(Long authId, Long orderId, Long flowId) {
HardThirdMiOrderEntity thirdMiOrder = hardThirdMiOrderMapper.getByAuthId(authId);
if (ObjectUtil.isEmpty(thirdMiOrder)) {
log.error("|免密服务下单|订单不存在,authId|{}", authId);
return null;
}
ZhimaCreditPayafteruseCreditagreementQueryResponse signObj = JSONUtil.toBean(thirdMiOrder.getOrgSignJson(), ZhimaCreditPayafteruseCreditagreementQueryResponse.class);
if (ObjectUtil.isEmpty(signObj)) {
log.error("|免密服务下单|signObj为空,授权错误,authId|{}", authId);
return null;
}
HardThirdMiOrderEntity updateObj = new HardThirdMiOrderEntity();
updateObj.setId(thirdMiOrder.getId());
updateObj.setOrderId(orderId);
updateObj.setFlowId(flowId);
updateObj.setOutOrderNo(String.valueOf(orderId));
ZhimaCreditPayafteruseCreditbizorderOrderRequest request = new ZhimaCreditPayafteruseCreditbizorderOrderRequest();
ZhimaCreditPayafteruseCreditbizorderOrderModel model = new ZhimaCreditPayafteruseCreditbizorderOrderModel();
// 设置商户外部订单号
model.setOutOrderNo(String.valueOf(orderId));
// 设置芝麻开通协议号
model.setCreditAgreementId(signObj.getCreditAgreementId());
// 设置芝麻外部类目
model.setCategoryId("credit_pay_after_use");
// 设置芝麻产品代码
model.setProductCode("CREDIT_PAY_AFTER_USE");
// 设置订单标题
model.setSubject("浦江智能柜芝麻先享");
// 设置订单描述
model.setBody("浦江智能柜芝麻先享");
request.setBizModel(model);
try {
ZhimaCreditPayafteruseCreditbizorderOrderResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|免密服务下单|失败,json|{}", response.getBody());
return null;
}
updateObj.setThirdOrderNo(response.getCreditBizOrderId());
updateObj.setOrgOrderJson(JSONUtil.toJsonStr(response));
// 一般是芝麻信用评估不通过、未开通等
if (List.of("ZHIMA_CHECK_NO_PASS", "ZHIMA_EVALUATE_NO_PASS", "CREDIT_AGREEMENT_INVALID").contains(response.getCode())) {
}
response.getCode();
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|免密服务下单|异常", e);
return null;
} finally {
hardThirdMiOrderMapper.updateById(updateObj);
}
}
/**
* 创建免密服务订单(风险评估)
*/
private ZhimaCreditPayafteruseCreditbizorderCreateResponse miDynamicCreate(Long authId, Long orderId) {
ZhimaCreditPayafteruseCreditbizorderCreateRequest request = new ZhimaCreditPayafteruseCreditbizorderCreateRequest();
ZhimaCreditPayafteruseCreditbizorderCreateModel model = new ZhimaCreditPayafteruseCreditbizorderCreateModel();
// 设置商户外部订单号
model.setOutOrderNo(String.valueOf(orderId));
model.setZmServiceId(conf.getZmServiceId());
model.setAmountType("RISK_AMOUNT");
model.setCategoryId("credit_pay_after_use");
model.setSubject("浦江智能柜芝麻先享");
model.setBody("浦江智能柜芝麻先享");
request.setBizModel(model);
try {
ZhimaCreditPayafteruseCreditbizorderCreateResponse response = getClient().sdkExecute(request);
if (!response.isSuccess()) {
log.error("|创建免密服务订单(风险评估)|失败,json|{}", response.getBody());
return null;
}
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|创建免密服务订单(风险评估)|异常", e);
return null;
}
}
/**
* 创建支付宝免密订单
*/
@Override
public AlipayTradeCreateResponse miCreateOrder(String openId, Long authId, Long userId, UserTypeEnum userType) {
int depositPricePrice = 10;
HardThirdMiOrderEntity thirdOrder = new HardThirdMiOrderEntity();
thirdOrder.setBizType(HardThirdMiTypeEnum.MI_ALIPAY.getType());
thirdOrder.setAuthId(authId);
thirdOrder.setUserId(userId);
thirdOrder.setDepositPrice(depositPricePrice);
thirdOrder.setUserType(userType.getStatus());
thirdOrder.setCreateOrderTime(LocalDateTime.now());
thirdOrder.setOrderStatus(HardThirdMiStatusEnum.CREATE_ORDER.getType());
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
try {
JSONObject bizContent = new JSONObject();
// 设置商户订单号
bizContent.putOnce("out_trade_no", String.valueOf(authId));
// 设置订单标题
bizContent.putOnce("subject", "浦江智能柜芝麻先享");
// 设置订单附加信息
bizContent.putOnce("body", "浦江智能柜芝麻先享");
// 设置订单金额
bizContent.putOnce("total_amount", new BigDecimal(depositPricePrice).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString());
// 固定
bizContent.putOnce("product_code", "JSAPI_PAY");
// 用户登录id
bizContent.putOnce("buyer_open_id", openId);
bizContent.putOnce("op_buyer_open_id", openId);
bizContent.putOnce("op_app_id", conf.getAppId());
// 订单超时时间(1天)
bizContent.putOnce("time_expire", LocalDateTimeUtil.format(LocalDateTime.now().plusDays(1), DatePattern.NORM_DATETIME_FORMATTER));
JSONObject extraParam = new JSONObject();
extraParam.putOnce("zmServiceId", conf.getZmServiceId());
extraParam.putOnce("creditTradeScene", "CREDIT_PAY");
bizContent.putOnce("extend_params", extraParam);
request.setBizContent(bizContent.toString());
AlipayTradeCreateResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|创建支付宝订单|失败,json|{}", response.getBody());
return null;
}
log.info("|创建支付宝订单|成功,json|{}", response.getBody());
thirdOrder.setOutOrderNo(String.valueOf(authId));
thirdOrder.setThirdOrderNo(response.getTradeNo());
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|创建支付宝订单|意外的错误", e);
return null;
} finally {
hardThirdMiOrderMapper.insert(thirdOrder);
}
}
/**
* 查询支付宝免密订单
*/
@Override
public ZhimaCreditPayafteruseCreditbizorderQueryResponse miQueryOrder(String alipayOrderNo, Long authId) {
ZhimaCreditPayafteruseCreditbizorderQueryRequest request = new ZhimaCreditPayafteruseCreditbizorderQueryRequest();
ZhimaCreditPayafteruseCreditbizorderQueryModel model = new ZhimaCreditPayafteruseCreditbizorderQueryModel();
if (ObjectUtil.isNotEmpty(alipayOrderNo)) {
model.setCreditBizOrderId(alipayOrderNo);
}
if (ObjectUtil.isNotEmpty(authId)) {
model.setOutOrderNo(String.valueOf(authId));
}
request.setBizModel(model);
try {
ZhimaCreditPayafteruseCreditbizorderQueryResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|查询支付宝免密订单|失败,json|{}", response.getBody());
return null;
}
log.info("|查询支付宝免密订单|成功,json|{}", response.getBody());
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|查询支付宝免密订单|意外的错误", e);
}
return null;
}
/**
* 支付宝免密扣款
*/
@Override
public boolean miPay(HardThirdMiOrderEntity thirdOrder, int totalPrice) {
HardThirdMiOrderEntity updateObj = new HardThirdMiOrderEntity();
updateObj.setId(thirdOrder.getId());
updateObj.setPayOrderTime(LocalDateTime.now());
updateObj.setOrderPrice(totalPrice);
updateObj.setPayPrice(totalPrice);
updateObj.setOrderStatus(HardThirdMiStatusEnum.PAY_ERROR.getType());
AlipayTradeOrderPayRequest request = new AlipayTradeOrderPayRequest();
AlipayTradeOrderPayModel model = new AlipayTradeOrderPayModel();
model.setOutRequestNo(String.valueOf(thirdOrder.getOrderId()));
model.setTradeNo(thirdOrder.getThirdOrderNo());
model.setFulfillmentAmount(new BigDecimal(totalPrice).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).toString());
model.setOrderPayMode("CREDIT_FULFILLMENT_ZM");
try {
request.setBizModel(model);
AlipayTradeOrderPayResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|支付宝免密扣款|失败,json|{}", response.getBody());
return false;
}
log.info("|支付宝免密扣款|成功,json|{}", response.getBody());
if (ObjectUtil.equals(response.getCode(), "10000")) {
updateObj.setOrderStatus(HardThirdMiStatusEnum.PAY_SUCCESS.getType());
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
log.error("|支付宝免密扣款|异常", e);
return false;
} finally {
hardThirdMiOrderMapper.updateById(updateObj);
}
}
/**
* 支付宝免密(取消/退款)
*/
@Override
public AlipayTradeRefundResponse miCancelOrRefund(HardThirdMiOrderEntity thirdOrder) {
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
JSONObject bizContent = new JSONObject();
// 订单总金额
bizContent.putOnce("refund_amount", new BigDecimal(thirdOrder.getRefundId()).divide(BigDecimal.valueOf(thirdOrder.getRefundPrice()), 2, RoundingMode.HALF_UP));
// 商家订单唯一号
bizContent.putOnce("out_trade_no", String.valueOf(thirdOrder.getAuthId()));
bizContent.putOnce("out_request_no", String.valueOf(thirdOrder.getRefundId()));
//扩展参数
JSONObject extendParam = new JSONObject();
extendParam.putOnce("is_fulfilled", "true");
bizContent.putOnce("extend_params", extendParam);
try {
request.setBizContent(bizContent.toString());
AlipayTradeRefundResponse response = getClient().execute(request);
if (!response.isSuccess()) {
log.error("|支付宝免密(取消/退款)|失败,json|{}", response.getBody());
return null;
}
log.info("|支付宝免密(取消/退款)|成功,json|{}", response.getBody());
return response;
} catch (Exception e) {
e.printStackTrace();
log.error("|支付宝免密(取消/退款)|异常", e);
return null;
}
}
}
@@ -16,6 +16,7 @@ import com.bsd.pjcloud.hard.api.vo.manager.HardDoorCabinetCodeVo;
import com.bsd.pjcloud.hard.api.vo.manager.HardDoorCabinetVo;
import com.bsd.pjcloud.hard.mapper.manager.HardDoorCabinetMapper;
import com.bsd.pjcloud.hard.service.HardDoorCabinetService;
import com.bsd.pjcloud.hard.service.MiniAlipayService;
import com.bsd.pjcloud.thirdparty.vo.door.DoorStatusVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -40,6 +41,8 @@ public class HardDoorCabinetServiceImpl extends ServiceImpl<HardDoorCabinetMappe
private static final String TAG = "智能柜货柜";
private final MiniAlipayService miniAlipayService;
private final RemoteFileService remoteFileService;
@Override
@@ -105,6 +108,12 @@ public class HardDoorCabinetServiceImpl extends ServiceImpl<HardDoorCabinetMappe
updateObj.setId(cabinetDetail.getId());
updateObj.setQrCode(qrCode);
updateObj.setUrlQrCode(urlQrCode);
// 刷新支付宝二维码
String doorMiniQrCode = miniAlipayService.getDoorMiniQrCode(String.valueOf(cabinetDetail.getHardDoorId()), String.valueOf(cabinetDetail.getCabinetNo()));
if (ObjectUtil.isNotEmpty(doorMiniQrCode)) {
updateObj.setUrlAlipayQrCode(doorMiniQrCode);
}
// 刷新微信小程序
baseMapper.updateById(updateObj);
}
@@ -1,9 +1,16 @@
package com.bsd.pjcloud.hard.service.impl.order;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.entity.SysDept;
import com.bsd.pjcloud.admin.api.feign.RemoteDeptService;
@@ -13,6 +20,7 @@ import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.constant.order.HardHourTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.constant.total.DateRangeTypeEnum;
import com.bsd.pjcloud.hard.api.dto.order.HardCarDto;
@@ -22,6 +30,7 @@ import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductLikeTopDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSbVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByCanteenVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByClassifyVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo;
@@ -30,20 +39,21 @@ import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.service.HardCanteenTotalService;
import com.bsd.pjcloud.wallet.api.feign.RemoteMchService;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -168,7 +178,7 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
}
/**
* 食堂菜品购买统计
* 食堂菜品购买统计(按天统计)
*/
@Override
public Page<HardCanteenProductTotalVo> productTotal(Page page, HardOrderDto dto, DataScope dataScope) {
@@ -183,6 +193,25 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
return pageList;
}
/**
* 食堂菜品购买部门统计(按月统计)
*/
@Override
public Page<HardCanteenProductTotalVo> productTotalByMonth(Page page, HardOrderDto dto, DataScope dataScope) {
dto.setOrderStatusCodes(HardOrderStatusEnum.getPaySuccessCodes());
Page<HardCanteenProductTotalVo> pageList = hardCarMapper.productTotalByMonth(page, dto, dataScope);
if (ObjectUtil.isNotEmpty(pageList)) {
for (HardCanteenProductTotalVo v : pageList.getRecords()) {
if (ObjectUtil.isEmpty(v.getCreateTime()) && ObjectUtil.isNotEmpty(v.getCreateTimeStr())) {
v.setCreateTime(LocalDateTimeUtil.parse(v.getCreateTimeStr() + "-01", DatePattern.NORM_DATE_PATTERN));
}
LocalDate localDate = v.getCreateTime().toLocalDate();
v.setUniqueCode(localDate + "_" + v.getHourType());
}
}
return pageList;
}
/**
* 菜品出售统计
*/
@@ -236,6 +265,236 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
return list;
}
/**
* 食堂菜品购买统计导出(按天统计)
*/
@Override
public void productTotalExportByDay(HttpServletResponse response, HardOrderDto dto) {
dto.setOrderStatusCodes(HardOrderStatusEnum.getPaySuccessCodes());
// 查询食堂
String mchName = "所有";
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
MchManageVo mch = remoteMchService.getById(dto.getMerchantId()).getData();
if (ObjectUtil.isNotEmpty(mch)) {
mchName = mch.getName();
}
}
// 标题
// 格式-2025年县府一楼食堂就餐情况统计表
String title = LocalDateTimeUtil.format(dto.getCreateTimeList()[0].toLocalDate(), DatePattern.CHINESE_DATE_PATTERN) + "至" + LocalDateTimeUtil.format(dto.getCreateTimeList()[1].toLocalDate(), DatePattern.CHINESE_DATE_PATTERN) + mchName + "就餐情况统计表";
// 选择的天数
List<LocalDate> dateRangeList = getDateRangeList(dto.getCreateTimeList()[0].toLocalDate(), dto.getCreateTimeList()[1].toLocalDate());
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(ResourceUtil.getStream("file/食堂菜品购买统计(按天).xlsx")).inMemory(true).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
Map<String, Object> map = new HashMap<String, Object>();
map.put("title", title);
// 总金额
double sumMorningPrice = 0;
long sumMorningTimeCount = 0;
double sumNoonPrice = 0;
long sumNoonTimeCount = 0;
double sumEveningPrice = 0;
long sumEveningTimeCount = 0;
Page<HardCanteenProductTotalVo> page = productTotal(new Page(1, 2000), dto, null);
List<HardCanteenProductTotalVo> records = page.getRecords();
// 开始处理excel
List<Map<String, Object>> excelList = new LinkedList<>();
for (LocalDate v : dateRangeList) {
Map<String, Object> excelMap = new HashMap<String, Object>();
String timeStr = "";
double morningPrice = 0;
long morningTimeCount = 0;
double noonPrice = 0;
long noonTimeCount = 0;
double eveningPrice = 0;
long eveningTimeCount = 0;
double colPrice = 0;
long colTimeCount = 0;
// 早
HardCanteenProductTotalVo morning = records.stream().filter(item -> ObjectUtil.equals(item.getHourType(), HardHourTypeEnum.MORNING.getType()) && ObjectUtil.equals(item.getCreateTime().toLocalDate(), v)).findFirst().orElse(null);
// 中
HardCanteenProductTotalVo noon = records.stream().filter(item -> ObjectUtil.equals(item.getHourType(), HardHourTypeEnum.NOONING.getType()) && ObjectUtil.equals(item.getCreateTime().toLocalDate(), v)).findFirst().orElse(null);
// 晚
HardCanteenProductTotalVo evening = records.stream().filter(item -> ObjectUtil.equals(item.getHourType(), HardHourTypeEnum.NIGHT.getType()) && ObjectUtil.equals(item.getCreateTime().toLocalDate(), v)).findFirst().orElse(null);
if (ObjectUtil.isNotEmpty(v)) {
timeStr = LocalDateTimeUtil.format(v, DatePattern.NORM_DATE_PATTERN);
}
if (ObjectUtil.isNotEmpty(morning)) {
if (ObjectUtil.isNotEmpty(morning.getTotalPrice())) {
morningPrice = BigDecimal.valueOf(morning.getTotalPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
}
if (ObjectUtil.isNotEmpty(morning.getTimeCount())) {
morningTimeCount = morning.getTimeCount();
}
}
if (ObjectUtil.isNotEmpty(noon)) {
if (ObjectUtil.isNotEmpty(noon.getTotalPrice())) {
noonPrice = BigDecimal.valueOf(noon.getTotalPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
}
if (ObjectUtil.isNotEmpty(noon.getTimeCount())) {
noonTimeCount = noon.getTimeCount();
}
}
if (ObjectUtil.isNotEmpty(evening)) {
if (ObjectUtil.isNotEmpty(evening.getTotalPrice())) {
eveningPrice = BigDecimal.valueOf(evening.getTotalPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
}
if (ObjectUtil.isNotEmpty(evening.getTimeCount())) {
eveningTimeCount = evening.getTimeCount();
}
}
sumMorningPrice += morningPrice;
sumMorningTimeCount += morningTimeCount;
sumNoonPrice += noonPrice;
sumNoonTimeCount += noonTimeCount;
sumEveningPrice += eveningPrice;
sumEveningTimeCount += eveningTimeCount;
colPrice = morningPrice + noonPrice + eveningPrice;
colTimeCount = morningTimeCount + noonTimeCount + eveningTimeCount;
excelMap.put("timeStr", timeStr);
excelMap.put("morningPrice", morningPrice);
excelMap.put("morningTimeCount", morningTimeCount);
excelMap.put("noonPrice", noonPrice);
excelMap.put("noonTimeCount", noonTimeCount);
excelMap.put("eveningPrice", eveningPrice);
excelMap.put("eveningTimeCount", eveningTimeCount);
excelMap.put("colPrice", colPrice);
excelMap.put("colTimeCount", colTimeCount);
excelList.add(excelMap);
}
map.put("sumMorningPrice", sumMorningPrice);
map.put("sumMorningTimeCount", sumMorningTimeCount);
map.put("sumNoonPrice", sumNoonPrice);
map.put("sumNoonTimeCount", sumNoonTimeCount);
map.put("sumEveningPrice", sumEveningPrice);
map.put("sumEveningTimeCount", sumEveningTimeCount);
map.put("colPrice", sumMorningPrice + sumNoonPrice + sumEveningPrice);
map.put("colTimeCount", sumMorningTimeCount + sumNoonTimeCount + sumEveningTimeCount);
excelWriter.fill(map, writeSheet);
excelWriter.fill(excelList, fillConfig, writeSheet);
Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
if (ObjectUtil.isNotEmpty(workbook)) {
// 计算公式
workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
}
excelWriter.finish();
} catch (Exception e) {
e.printStackTrace();
log.error("|食堂菜品购买统计导出(按天统计)|导出数据异常error:{}", e.getMessage());
}
}
/**
* 食堂菜品购买统计导出(按月统计)
*/
@Override
public void productTotalExportByMonth(HttpServletResponse response, HardOrderDto dto) {
dto.setOrderStatusCodes(HardOrderStatusEnum.getPaySuccessCodes());
String createTimeYearStr = dto.getCreateTimeYearStr();
Integer createTimeYear = Integer.valueOf(createTimeYearStr);
// 查询食堂
String mchName = "所有";
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
MchManageVo mch = remoteMchService.getById(dto.getMerchantId()).getData();
if (ObjectUtil.isNotEmpty(mch)) {
mchName = mch.getName();
}
}
// 标题
// 格式-2025年县府一楼食堂就餐情况统计表
String title = createTimeYear + "年" + mchName + "就餐情况统计表";
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(ResourceUtil.getStream("file/食堂菜品购买统计(按月).xlsx")).inMemory(true).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
Map<String, Object> map = new HashMap<>();
map.put("title", title);
Page<HardCanteenProductTotalVo> page = productTotalByMonth(new Page(1L, 999L), dto, null);
List<HardCanteenProductTotalVo> records = page.getRecords();
// 填充数据
// 早
List<HardCanteenProductTotalVo> morningList = records.stream().filter(v -> ObjectUtil.equals(v.getHourType(), HardHourTypeEnum.MORNING.getType())).toList();
excelWriter.fill(productTotalExportByMonthToDefaulColExcelMap(morningList, createTimeYear, "morning"), fillConfig, writeSheet);
// 中
List<HardCanteenProductTotalVo> noonList = records.stream().filter(v -> ObjectUtil.equals(v.getHourType(), HardHourTypeEnum.NOONING.getType())).toList();
excelWriter.fill(productTotalExportByMonthToDefaulColExcelMap(noonList, createTimeYear, "noon"), fillConfig, writeSheet);
// 晚
List<HardCanteenProductTotalVo> nightList = records.stream().filter(v -> ObjectUtil.equals(v.getHourType(), HardHourTypeEnum.NIGHT.getType())).toList();
excelWriter.fill(productTotalExportByMonthToDefaulColExcelMap(nightList, createTimeYear, "night"), fillConfig, writeSheet);
excelWriter.fill(map, writeSheet);
Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
if (ObjectUtil.isNotEmpty(workbook)) {
// 计算公式
workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
}
excelWriter.finish();
} catch (Exception e) {
e.printStackTrace();
log.error("|食堂菜品购买统计导出(按月统计)|导出数据异常error:{}", e.getMessage());
}
}
private List<Map<String, Object>> productTotalExportByMonthToDefaulColExcelMap(List<HardCanteenProductTotalVo> records, int year, String prefix) {
List<Map<String, Object>> list = new LinkedList<>();
if (ObjectUtil.isEmpty(records)) return list;
List<HardCanteenProductTotalVo> sqlList = new LinkedList<>();
List<LocalDate> monthlyRanges = new LinkedList<>();
for (Month month : Month.values()) {
LocalDate localDate = LocalDate.of(year, month.getValue(), 1);
monthlyRanges.add(localDate);
}
for (LocalDate i : monthlyRanges) {
HardCanteenProductTotalVo target = records.stream().filter(v -> ObjectUtil.equals(v.getCreateTime().toLocalDate(), i)).findFirst().orElse(null);
if (ObjectUtil.isEmpty(target)) {
HardCanteenProductTotalVo defaultVo = new HardCanteenProductTotalVo();
defaultVo.setCreateTime(i.atStartOfDay());
defaultVo.setCreateTimeStr(LocalDateTimeUtil.format(i, DatePattern.NORM_MONTH_PATTERN));
sqlList.add(defaultVo);
} else {
sqlList.add(target);
}
}
double sumTotalPrice = 0;
long sumTimeCount = 0;
String mapKey = prefix + "Col";
for (HardCanteenProductTotalVo i : sqlList) {
double totalPrice = 0;
if (ObjectUtil.isNotEmpty(i.getTotalPrice())) {
totalPrice = BigDecimal.valueOf(i.getTotalPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).doubleValue();
}
list.add(Map.of(mapKey, totalPrice));
sumTotalPrice += totalPrice;
long timeCount = 0;
if (ObjectUtil.isNotEmpty(i.getTimeCount())) {
timeCount = i.getTimeCount();
}
list.add(Map.of(mapKey, timeCount));
sumTimeCount += timeCount;
}
list.add(Map.of(mapKey, sumTotalPrice));
list.add(Map.of(mapKey, sumTimeCount));
return list;
}
/**
* 为HardCanteenProductTotalVo增加部门信息
*/
@@ -367,4 +626,14 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
}
}
}
public List<LocalDate> getDateRangeList(LocalDate startDate, LocalDate endDate) {
List<LocalDate> dateList = new ArrayList<>();
LocalDate currentDate = startDate;
while (!currentDate.isAfter(endDate)) {
dateList.add(currentDate);
currentDate = currentDate.plusDays(1);
}
return dateList;
}
}
@@ -1,11 +1,10 @@
package com.bsd.pjcloud.hard.service.impl.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayTradeOrderPayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -24,6 +23,7 @@ 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.MerchantTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.UserTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
@@ -31,12 +31,15 @@ import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.hard.api.constant.HardProductNatureEnum;
import com.bsd.pjcloud.hard.api.constant.HardThirdMiStatusEnum;
import com.bsd.pjcloud.hard.api.constant.HardTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardHourTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
import com.bsd.pjcloud.hard.api.dto.ali.AliMicropayDto;
import com.bsd.pjcloud.hard.api.dto.ali.AliReverseDto;
import com.bsd.pjcloud.hard.api.dto.hard.HandCancelActCodeDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardDoneHardQrCodeScanOrderDto;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
import com.bsd.pjcloud.hard.api.dto.hard.HandCancelCodeDto;
@@ -50,6 +53,7 @@ import com.bsd.pjcloud.hard.api.dto.spu.DeductionSpuStockDto;
import com.bsd.pjcloud.hard.api.dto.wechat.WechantReverseDto;
import com.bsd.pjcloud.hard.api.dto.wechat.WechatMicropayDto;
import com.bsd.pjcloud.hard.api.entity.HardApptEntity;
import com.bsd.pjcloud.hard.api.entity.HardThirdMiOrderEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
@@ -62,18 +66,16 @@ import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCreateHardQrCodeScanOrderVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
import com.bsd.pjcloud.hard.api.vo.wechat.WechatMicropayVo;
import com.bsd.pjcloud.hard.mapper.HardThirdMiOrderMapper;
import com.bsd.pjcloud.hard.mapper.manager.HardManagerMapper;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.service.*;
import com.bsd.pjcloud.supermarket.api.feign.RemoteMallProductService;
import com.bsd.pjcloud.supermarket.api.feign.RemoteShopSkuService;
import com.bsd.pjcloud.supermarket.api.feign.RemoteShopSpuService;
import com.bsd.pjcloud.supermarket.api.feign.RemoteSupermarketSpuService;
import com.bsd.pjcloud.supermarket.dto.MallProductStockChangeDTO;
import com.bsd.pjcloud.supermarket.dto.SkuStockChangeDTO;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuUpdateStockReqDTO;
import com.bsd.pjcloud.supermarket.entity.ShopSkuEntity;
import com.bsd.pjcloud.supermarket.vo.app.ShopSpuDetailAppVo;
import com.bsd.pjcloud.thirdparty.dto.ks.KsRecognitionCallbackDto;
import com.bsd.pjcloud.wallet.api.constant.WalletBizEnum;
import com.bsd.pjcloud.wallet.api.constant.WalletCodeBizEnum;
@@ -83,20 +85,20 @@ import com.bsd.pjcloud.wallet.api.constant.mch.WalletMchRulePriceTypeEnum;
import com.bsd.pjcloud.wallet.api.constant.mch.WalletMchSupType;
import com.bsd.pjcloud.wallet.api.dto.WalletBalanceTransactionDto;
import com.bsd.pjcloud.wallet.api.dto.act.ActCancelItemDto;
import com.bsd.pjcloud.wallet.api.dto.act.ActComCancelDto;
import com.bsd.pjcloud.wallet.api.entity.WalletCodeUseEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletManageEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletTransactionEntity;
import com.bsd.pjcloud.wallet.api.entity.act.ActCancelItemEntity;
import com.bsd.pjcloud.wallet.api.feign.*;
import com.bsd.pjcloud.wallet.api.utils.WalletDataUtil;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import com.bsd.pjcloud.wallet.api.vo.WalletManageVo;
import com.bsd.pjcloud.wallet.api.vo.WalletSettingVo;
import com.bsd.pjcloud.wallet.api.vo.act.ActCancelItemVo;
import com.bsd.pjcloud.wallet.api.vo.act.ActComItemVo;
import com.bsd.pjcloud.wallet.api.vo.mch.MchPickUpVo;
import com.bsd.pjcloud.wallet.api.vo.mch.MchRuleJoinDtoVo;
import jakarta.validation.Valid;
import lombok.Locked;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
@@ -138,6 +140,7 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
private final HardApptService hardApptService;
private final WechatPayService wechatPayService;
private final AlipayService alipayService;
private final MiniAlipayService miniAlipayService;
private final RemoteMchService remoteMchService;
private final RemoteMchPickUpService remoteMchPickUpService;
@@ -152,12 +155,14 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
private final RemoteOnlineCanteenSpuService onlineCanteenSpuService;
private final RemoteSupermarketSpuService supermarketSpuService;
private final RemoteShopSkuService remoteShopSkuService;
private final RemoteComActService remoteComActService;
private final RemoteActCancelService remoteActCancelService;
private final RemoteMallProductService remoteMallProductService;
private final HardManagerMapper hardManagerMapper;
private final StringRedisTemplate redisTemplate;
private final HardThirdMiOrderMapper hardThirdMiOrderMapper;
@Override
public Page<HardOrderVo> pagejoin(Page page, HardOrderDto dto) {
@@ -188,6 +193,17 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
return list;
}
/**
* 分页查询未识别订单
*/
@Override
public Page<HardOrderVo> noRecogScopePageJoin(Page page, HardOrderDto dto, DataScope dataScope) {
dto.setOrderPayTypeCodes(List.of(HardPayTypeEnum.HARD_DOOR_FREE_PAY.getType()));
dto.setOrderStatus(HardOrderStatusEnum.CREATE.getType());
Page<HardOrderVo> list = baseMapper.scopePageList(page, dto, dataScope);
disposeList(list.getRecords(), dto);
return list;
}
@Override
public HardOrderVo join(Long id) {
@@ -856,10 +872,27 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
* 创建智能柜订单
*/
@Override
public Long createHardDoorOrder(Long userId, Long hardId) {
// 查询用户
UserInfo userDetail = userService.getInnerByUserId(userId).getData();
if (ObjectUtil.isEmpty(userDetail)) throw new RuntimeException("创建智能柜订单失败,用户不存在");
public Long createHardDoorOrder(Long userId, UserTypeEnum userType, Long hardId) {
Long currentUserId = null;
Long currentUserDeptId = null;
Long currentWalletId = null;
HardOrderTypeEnum currentOrderType = HardOrderTypeEnum.BELOW;
if (ObjectUtil.equals(userType, UserTypeEnum.TOB)) {
currentOrderType = HardOrderTypeEnum.BELOW;
} else {
currentOrderType = HardOrderTypeEnum.TOC_VISITOR;
}
// 查询TOB用户
if (ObjectUtil.equals(userType, UserTypeEnum.TOB)) {
UserInfo userDetail = userService.getInnerByUserId(userId).getData();
if (ObjectUtil.isEmpty(userDetail)) throw new RuntimeException("创建智能柜订单失败,用户不存在");
currentUserId = userDetail.getSysUser().getUserId();
currentUserDeptId = userDetail.getSysUser().getDeptId();
}
// 查询TOC用户
else {
currentUserId = userId;
}
// 查询设备
HardManagerVo hard = hardManagerService.getByHardId(hardId);
if (ObjectUtil.isEmpty(hard)) throw new RuntimeException("创建智能柜订单失败,设备不存在");
@@ -867,19 +900,22 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
MchManageVo mch = remoteMchService.getById(hard.getMerchantId()).getData();
if (ObjectUtil.isEmpty(hard)) throw new RuntimeException("创建智能柜订单失败,商户不存在");
// 默认超市钱包
WalletManageEntity wallet = remoteWalletService.getWallet(userId, WalletTypeEnum.PAY).getData();
if (ObjectUtil.isEmpty(wallet)) throw new RuntimeException("创建智能柜订单失败,用户消费钱包不存在");
if (ObjectUtil.equals(userType, UserTypeEnum.TOB)) {
WalletManageEntity wallet = remoteWalletService.getWallet(userId, WalletTypeEnum.PAY).getData();
if (ObjectUtil.isEmpty(wallet)) throw new RuntimeException("创建智能柜订单失败,用户消费钱包不存在");
currentWalletId = wallet.getId();
}
HardOrderEntity orderObj = HardOrderEntity.builder()
.walletId(wallet.getId())
.walletId(currentWalletId)
.hardId(hardId)
.merchantType(mch.getTypes())
.merchantId(mch.getId())
.merchantDeptId(mch.getDeptId())
.userId(userDetail.getSysUser().getUserId())
.userDeptId(userDetail.getSysUser().getDeptId())
.userId(currentUserId)
.userDeptId(currentUserDeptId)
.sysType(HardTypeEnum.DOOR.getType())
.orderStatus(HardOrderStatusEnum.CREATE.getType())
.orderType(HardOrderTypeEnum.BELOW.getType())
.orderType(currentOrderType.getType())
.payType(HardPayTypeEnum.HARD_DOOR_FREE_PAY.getType())
.totalPrice(0)
.extraPrice(0)
@@ -936,8 +972,22 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
HardOrderEntity orderObj = baseMapper.selectById(updateObj.getId());
// 扣减库存
getSelf().fastenerInventory(orderObj, YesNoEnum.YES);
if (ObjectUtil.equals(dto.getOrderType(), HardOrderTypeEnum.TOC_VISITOR.getType())) {
HardThirdMiOrderEntity thirdOrder = hardThirdMiOrderMapper.getByOrderId(orderObj.getId());
if (ObjectUtil.isEmpty(thirdOrder)) {
log.error("|{}|智能柜订单结算,第三方免密订单不存在orderId|{}|", TAG, orderObj.getId());
} else {
boolean isPay = miniAlipayService.miPay(thirdOrder, totalPrice);
if (isPay) {
// 更新订单状态
getSelf().orderSuccess(dto, false);
}
}
}
// 钱包扣款
getSelf().fastReduceBalance(orderObj);
else {
getSelf().fastReduceBalance(orderObj);
}
return orderObj.getId();
}
@@ -978,15 +1028,18 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
// 是否需要核销
boolean isVerify = isVerify(hardPayType);
if (isWalletPay) {
WalletBalanceTransactionDto reduceBuild = new WalletBalanceTransactionDto();
reduceBuild.setWalletId(order.getWalletId());
reduceBuild.setPrice(order.getPayPrice());
reduceBuild.setBizId(String.valueOf(order.getId()));
reduceBuild.setBizType(WalletBizEnum.PAYMENT);
reduceBuild.setForce(true);
R<WalletTransactionEntity> reduceRes = walletTransactionService.reduceWalletBalance(reduceBuild);
if (reduceRes.getCode() != 0 || ObjectUtil.isEmpty(reduceRes.getData())) {
throw new RuntimeException("钱包扣款错误");
int payPrice = order.getTotalPrice() + order.getExtraPrice();
if (payPrice > 0) {
WalletBalanceTransactionDto reduceBuild = new WalletBalanceTransactionDto();
reduceBuild.setWalletId(order.getWalletId());
reduceBuild.setPrice(order.getPayPrice());
reduceBuild.setBizId(String.valueOf(order.getId()));
reduceBuild.setBizType(WalletBizEnum.PAYMENT);
reduceBuild.setForce(true);
R<WalletTransactionEntity> reduceRes = walletTransactionService.reduceWalletBalance(reduceBuild);
if (reduceRes.getCode() != 0 || ObjectUtil.isEmpty(reduceRes.getData())) {
throw new RuntimeException("钱包扣款错误");
}
}
}
// 订单成功
@@ -1098,6 +1151,93 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
return baseMapper.updateById(updateObj) > 0;
}
/**
* 核销活动二维码
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean handCancelActCode(HandCancelActCodeDto dto) {
// 1. 查看活动是否存在
ActComItemVo detail = remoteComActService.remoteGetComAct(dto.getActItemId(), dto.getUserId()).getData();
if (ObjectUtil.isEmpty(detail)) {
throw new RuntimeException("活动不存在");
}
// 2. 参加活动人员
UserInfo userInfo = userService.getInnerByUserId(detail.getUserId()).getData();
if (ObjectUtil.isEmpty(userInfo)) {
throw new RuntimeException("参加活动用户不存在");
}
SysUser sysUser = userInfo.getSysUser();
// 3. 查询设备
HardManagerVo hardDetail = hardManagerService.getByHardId(dto.getHardwareId());
if (ObjectUtil.isEmpty(hardDetail)) {
throw new RuntimeException("设备不存在");
}
// 4. 查询商户
MchManageVo mch = remoteMchService.getById(hardDetail.getMerchantId()).getData();
if (ObjectUtil.isEmpty(mch)) {
throw new RuntimeException("商户不存在");
}
// 5. 是否已经核销过
String errorMsg = remoteComActService.remoteIsCanCancel(dto.getActItemId(), dto.getUserId()).getData();
if (ObjectUtil.isNotEmpty(errorMsg)) {
throw new RuntimeException(errorMsg);
}
// 6. 钱包(默认饭卡钱包)
WalletManageEntity wallet = remoteWalletService.getWallet(dto.getUserId(), WalletTypeEnum.EAT).getData();
// 7. 创建订单
// 是否需要支付
boolean isPay = true;
// 门槛金额
// 减免金额
// 商品描述
// 优惠金额
int useAmountPrice = 0;
String orderDesc = "浦江活动商品 x *";
// 总金额,额外金额,支付金额
int totalPrice = 0, extraPrice = 0, payPrice = 0;
// 添加硬件订单
HardOrderEntity orderObj = HardOrderEntity.builder()
.androidOrderCode(null)
.userId(sysUser.getUserId())
.userDeptId(sysUser.getDeptId())
.walletId(wallet.getId())
.sysType(hardDetail.getType())
.hourType("-1")
.parentCarId(null)
.hardId(dto.getHardwareId())
.orderStatus(HardOrderStatusEnum.CREATE.getType())
.merchantId(mch.getId())
.merchantType(mch.getTypes())
.merchantDeptId(mch.getDeptId())
.deptId(hardDetail.getDeptId())
.orderType(HardOrderTypeEnum.RESERVE.getType())
.payType(HardPayTypeEnum.ACT_CANCEL.getType())
.orderSourceTypeId(dto.getActItemId())
.totalPrice(totalPrice)
.extraPrice(extraPrice)
.payPrice(totalPrice + extraPrice)
.isOfflineOrder(YesNoEnum.NO.getCode())
.productDesc(orderDesc)
.build();
baseMapper.insert(orderObj);
// 核销
ActComCancelDto cancelDto = new ActComCancelDto();
cancelDto.setActItemId(dto.getActItemId());
cancelDto.setUserId(dto.getUserId());
cancelDto.setOrderId(orderObj.getId());
cancelDto.setUseAmountPrice(useAmountPrice);
Boolean isCancelSuccess = remoteComActService.remoteDoCancel(cancelDto).getData();
if (!isCancelSuccess) {
throw new RuntimeException("核销失败");
}
// 钱包扣款
getSelf().fastReduceBalance(orderObj);
return true;
}
@Override
// @GlobalTransactional
@Transactional(rollbackFor = Exception.class)
@@ -2,7 +2,17 @@ package com.bsd.pjcloud.hard.service.impl.order;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.DeptAllListDto;
import com.bsd.pjcloud.admin.api.entity.SysDept;
@@ -13,16 +23,13 @@ import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.datascope.DataScopeFuncEnum;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.hard.api.constant.HardTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
import com.bsd.pjcloud.hard.api.constant.refund.HardRefundStatusEnum;
import com.bsd.pjcloud.hard.api.constant.refund.HardSaleStatusEnum;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
import com.bsd.pjcloud.hard.api.dto.hard.CurrentUserHardTypeInfoDto;
import com.bsd.pjcloud.hard.api.dto.order.HardChartLatitudeVo;
import com.bsd.pjcloud.hard.api.dto.order.HardDeptTotalDto;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderSumAndCountDto;
import com.bsd.pjcloud.hard.api.dto.order.*;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.utils.HardUtil;
import com.bsd.pjcloud.hard.api.vo.order.*;
@@ -37,21 +44,22 @@ import com.bsd.pjcloud.wallet.api.feign.RemoteWalletTransactionService;
import com.bsd.pjcloud.wallet.api.utils.WalletDataUtil;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import com.bsd.pjcloud.wallet.api.vo.WalletTransactionSumAndCountVo;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.math.RoundingMode;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@Validated
@@ -169,7 +177,6 @@ public class HardOrderTotalServiceImpl implements HardOrderTotalService {
refundDto.setRefundStatusCodes(List.of(HardSaleStatusEnum.COMPLETE.getStatus()));
DataScope refundDataScope = DataScope.of();
refundDataScope.setScopeDeptName("merchant_dept_id");
List<HardOrderCsVo> refundList = hardOrderMapper.listRefundCs(refundDto, refundDataScope);
// 有退款没有流水的情况
if (ObjectUtil.isAllNotEmpty(totalList, refundList)) {
@@ -225,7 +232,10 @@ public class HardOrderTotalServiceImpl implements HardOrderTotalService {
if (ObjectUtil.isNotEmpty(deptMap)) {
for (HardOrderCsVo v : totalList) {
if (ObjectUtil.isEmpty(v.getMerchantDeptId())) continue;
v.setMerchantDeptName(deptMap.get(v.getMerchantDeptId()).getName());
SysDept targetDept = deptMap.get(v.getMerchantDeptId());
if (ObjectUtil.isNotEmpty(targetDept)) {
v.setMerchantDeptName(targetDept.getName());
}
}
}
}
@@ -233,6 +243,105 @@ public class HardOrderTotalServiceImpl implements HardOrderTotalService {
return totalList;
}
/**
* 商户交易记录(按商户、月)查询
*/
@Override
public Page<HardOrderCsVo> pageListCsByMonth(Page page, HardOrderDto dto) {
PjcloudUser user = SecurityUtils.getUser();
if (ObjectUtil.isEmpty(dto.getMchTypeCodes())) {
CurrentUserHardTypeInfoDto hardTypeInfo = hardManagerService.getCurrentUserHardTypeInfo(user);
dto.setMchTypeCodes(hardTypeInfo.getHardTypeList());
} else {
dto.setMchTypeCodes(dto.getMchTypeCodes());
}
// 查询总流水
HardOrderDto totalDto = BeanUtil.toBean(dto, HardOrderDto.class);
totalDto.setOrderStatusCodes(HardOrderStatusEnum.getPayPrice());
totalDto.setPayTimeYearStr(dto.getPayTimeYearStr());
DataScope totalDataScope = DataScope.of();
totalDataScope.setScopeDeptName("merchant_dept_id");
Page<HardOrderCsVo> totalPage = hardOrderMapper.pageCsByMonth(page, totalDto, totalDataScope);
List<HardOrderCsVo> totalList = totalPage.getRecords();
// 扣款总流水
HardOrderDto refundDto = BeanUtil.toBean(dto, HardOrderDto.class);
refundDto.setPayTimeList(null);
refundDto.setRefundTimeList(dto.getPayTimeList());
refundDto.setAuditTimeYearStr(dto.getPayTimeYearStr());
refundDto.setPayTimeYearStr(null);
refundDto.setOrderStatusCodes(HardOrderStatusEnum.getPayErrorCodes());
refundDto.setRefundStatusCodes(List.of(HardSaleStatusEnum.COMPLETE.getStatus()));
if (ObjectUtil.isNotEmpty(dto.getMchIds())) {
refundDto.setMchIds(dto.getMchIds());
}
DataScope refundDataScope = DataScope.of();
refundDataScope.setScopeDeptName("merchant_dept_id");
List<HardOrderCsVo> refundList = hardOrderMapper.listRefundCsByMonth(refundDto, refundDataScope);
// 有退款没有流水的情况
if (ObjectUtil.isAllNotEmpty(totalList, refundList)) {
for (HardOrderCsVo refund : refundList) {
HardOrderCsVo target = totalList.stream().filter(v -> ObjectUtil.equals(refund.getMerchantId(), v.getMerchantId()) && ObjectUtil.equals(refund.getDay(), v.getDay())).findFirst().orElse(null);
if (ObjectUtil.isEmpty(target)) {
HardOrderCsVo entity = BeanUtils.toBean(refund, HardOrderCsVo.class);
entity.setTotalPayPrice(BigDecimal.ZERO);
entity.setTotalPayCount(BigDecimal.ZERO);
totalList.add(entity);
}
}
}
for (HardOrderCsVo v : totalList) {
// 退款
if (ObjectUtil.isNotEmpty(refundList)) {
refundList.stream().filter(i -> ObjectUtil.equals(i.getMerchantId(), v.getMerchantId()) && ObjectUtil.equals(i.getDay(), v.getDay())).findFirst().ifPresent(i -> {
v.setTotalRefundPrice(i.getTotalPayPrice());
v.setTotalRefundCount(i.getTotalPayCount());
});
}
// 消费净金额
if (ObjectUtil.isNotEmpty(v.getTotalPayPrice())) {
BigDecimal refundPrice = BigDecimal.ZERO;
if (ObjectUtil.isNotEmpty(v.getTotalRefundPrice())) {
refundPrice = v.getTotalRefundPrice();
}
v.setTotalProfitPrice(v.getTotalPayPrice().subtract(refundPrice));
}
// 消费净次数
if (ObjectUtil.isNotEmpty(v.getTotalPayCount())) {
BigDecimal refundCount = BigDecimal.ZERO;
if (ObjectUtil.isNotEmpty(v.getTotalRefundCount())) {
refundCount = v.getTotalRefundCount();
}
v.setTotalProfitCount(v.getTotalPayCount().subtract(refundCount));
}
}
// 聚合一下数据
if (ObjectUtil.isNotEmpty(totalList)) {
// 商户
List<Long> mchIds = totalList.stream().map(HardOrderCsVo::getMerchantId).distinct().toList();
if (ObjectUtil.isNotEmpty(mchIds)) {
List<MchManageVo> mchList = remoteMchService.getByIds(mchIds).getData();
if (ObjectUtil.isNotEmpty(mchList)) {
WalletDataUtil.convertMchList(totalList, CollectionUtils.convertMap(mchList, MchManageVo::getId));
}
}
// 商户部门
List<Long> mchDeptIds = totalList.stream().map(HardOrderCsVo::getMerchantDeptId).distinct().toList();
if (ObjectUtil.isNotEmpty(mchDeptIds)) {
Map<Long, SysDept> deptMap = remoteDeptService.getDeptByDeptIds(mchDeptIds).getData();
if (ObjectUtil.isNotEmpty(deptMap)) {
for (HardOrderCsVo v : totalList) {
if (ObjectUtil.isEmpty(v.getMerchantDeptId())) continue;
SysDept targetDept = deptMap.get(v.getMerchantDeptId());
if (ObjectUtil.isNotEmpty(targetDept)) {
v.setMerchantDeptName(targetDept.getName());
}
}
}
}
}
return totalPage;
}
@Override
public List<HardOrderCsVo> listCsByDay(Page page, HardOrderDto dto, PjcloudUser user) {
// 查询总流水
@@ -675,4 +784,180 @@ public class HardOrderTotalServiceImpl implements HardOrderTotalService {
result.setAllTotal(totalList);
return result;
}
/**
* 商户交易记录导出(按月)
*/
@Override
public void exportCsByMonth(HttpServletResponse response, HardOrderDto dto) {
// 查询所有有订单或者退款的店铺记录
List<Long> mchIds = new ArrayList<>();
if (ObjectUtil.isNotEmpty(mchIds)) {
mchIds = new ArrayList<>(dto.getMchIds());
}
// 查询总流水
if (ObjectUtil.isEmpty(mchIds)) {
HardSelectOrderMerchIdsDto merchQuery = new HardSelectOrderMerchIdsDto();
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
merchQuery.setMerchIds(List.of(dto.getMerchantId()));
}
if (ObjectUtil.isNotEmpty(dto.getMchTypeCodes())) {
merchQuery.setMerchTypes(dto.getMchTypeCodes());
}
if (ObjectUtil.isNotEmpty(dto.getCreateTimeList())) {
merchQuery.setCreateTimeList(dto.getCreateTimeList());
}
if (ObjectUtil.isNotEmpty(dto.getPayTimeYearStr())) {
merchQuery.setPayTimeYearStr(dto.getPayTimeYearStr());
}
mchIds = hardOrderMapper.selectOrderMerchIds(merchQuery);
}
List<List<Long>> chuckMchIds = ListUtil.split(mchIds, 5);
List<MchManageVo> mchList = remoteMchService.getByIds(mchIds).getData();
Map<String, Object> map = new HashMap<String, Object>();
// 查询食堂
String mchName = "所有";
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
MchManageVo mch = remoteMchService.getById(dto.getMerchantId()).getData();
if (ObjectUtil.isNotEmpty(mch)) {
mchName = mch.getName();
}
}
// 标题
// 格式-2025年浦江大饭店合作商家流水情况统计表
String title = dto.getPayTimeYearStr() + "年" + mchName + "合作商家流水情况统计表";
map.put("title", title);
// 年份
int payTimeYearint = Integer.parseInt(dto.getPayTimeYearStr());
ByteArrayOutputStream tempExcel = new ByteArrayOutputStream();
try {
ExcelWriter excelWriter = EasyExcel.write(tempExcel).withTemplate(ResourceUtil.getStream("file/商户交易金额汇总(按月).xlsx")).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
List<Map<String, Object>> excelTempMapList = new ArrayList<>();
for (int i = 0; i < mchIds.size(); i++) {
Long currentMchId = mchIds.get(i);
Map<String, Object> excelMap = new LinkedHashMap<>();
for (int j = 0; j <= 26; j++) {
String key = String.format("col%d", j);
String value = "";
if (j == 0) {
value = String.format("{col_%d.col}", currentMchId);
}
excelMap.put(key, value);
}
excelTempMapList.add(excelMap);
}
excelWriter.fill(Map.of("total", "{total.total}", "title", "{title}"), writeSheet);
excelWriter.fill(excelTempMapList, fillConfig, writeSheet);
excelWriter.finish();
} catch (Exception e) {
e.printStackTrace();
}
// 导出tempExcel用于调试
// FileUtil.writeBytes(tempExcel.toByteArray(), "/Users/dengzhangchen/Downloads/debug_hard_order_" + System.currentTimeMillis() + ".xlsx");
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(new ByteArrayInputStream(tempExcel.toByteArray())).build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).forceNewRow(Boolean.TRUE).build();
// 按月份总计
List<HardOrderCsVo.Month> monthTotalList = new LinkedList<>();
for (Month month : Month.values()) {
HardOrderCsVo.Month defaulMonthTotal = new HardOrderCsVo.Month();
LocalDate monthDate = LocalDate.of(payTimeYearint, month.getValue(), 1);
String monthStr = LocalDateTimeUtil.format(monthDate, DatePattern.NORM_MONTH_PATTERN);
defaulMonthTotal.setDay(monthStr);
defaulMonthTotal.setTotalProfitPrice(0);
defaulMonthTotal.setTotalProfitCount(0);
monthTotalList.add(defaulMonthTotal);
}
for (List<Long> ids : chuckMchIds) {
dto.setMchIds(ids);
Page<HardOrderCsVo> page = pageListCsByMonth(new Page(1L, 999L), dto);
List<HardOrderCsVo> records = page.getRecords();
if (ObjectUtil.isEmpty(records)) break;
for (Long id : ids) {
List<Map<String, Object>> excelMapList = new LinkedList<Map<String, Object>>();
// 先查询商户名
String currentMchName = "未知商户";
MchManageVo mchDetail = mchList.stream().filter(m -> ObjectUtil.equals(m.getId(), id)).findFirst().orElse(null);
if (ObjectUtil.isNotEmpty(mchDetail) && ObjectUtil.isNotEmpty(mchDetail.getName())) {
currentMchName = mchDetail.getName();
}
excelMapList.add(Map.of("col", currentMchName));
excelMapList.addAll(disposeCsByMonth(id, records, monthTotalList, payTimeYearint));
excelWriter.fill(new FillWrapper("col_" + id, excelMapList), fillConfig, writeSheet);
}
}
// 统计
double sumTotalPrice = 0;
long sumTimeCount = 0;
List<Map<String, Object>> excelTotalMapList = new LinkedList<Map<String, Object>>();
for (HardOrderCsVo.Month total : monthTotalList) {
excelTotalMapList.add(Map.of("total", total.getTotalProfitPrice()));
excelTotalMapList.add(Map.of("total", total.getTotalProfitCount()));
sumTotalPrice += total.getTotalProfitPrice();
sumTimeCount += total.getTotalProfitCount();
}
excelTotalMapList.add(Map.of("total", sumTotalPrice));
excelTotalMapList.add(Map.of("total", sumTimeCount));
excelWriter.fill(new FillWrapper("total", excelTotalMapList), fillConfig, writeSheet);
excelWriter.fill(map, writeSheet);
} catch (Exception e) {
e.printStackTrace();
log.error("|商户交易记录导出(按月)|以外的错误,error:{}", e.getMessage());
}
}
public List<Map<String, Object>> disposeCsByMonth(Long mchId, List<HardOrderCsVo> list, List<HardOrderCsVo.Month> monthTotalList, Integer yearStr) {
List<LocalDate> monthlyRanges = new LinkedList<>();
for (Month month : Month.values()) {
LocalDate localDate = LocalDate.of(yearStr, month.getValue(), 1);
monthlyRanges.add(localDate);
}
List<Map<String, Object>> listMap = new LinkedList<>();
List<HardOrderCsVo> sqlList = new LinkedList<>();
for (LocalDate i : monthlyRanges) {
String monthStr = LocalDateTimeUtil.format(i, DatePattern.NORM_MONTH_PATTERN);
HardOrderCsVo target = list.stream().filter(v -> ObjectUtil.equals(v.getDay(), monthStr) && ObjectUtil.equals(v.getMerchantId(), mchId)).findFirst().orElse(null);
if (ObjectUtil.isEmpty(target)) {
HardOrderCsVo defaultVo = new HardOrderCsVo();
defaultVo.setTotalProfitPrice(BigDecimal.ZERO);
defaultVo.setTotalProfitCount(BigDecimal.ZERO);
sqlList.add(defaultVo);
} else {
sqlList.add(target);
}
}
double sumTotalPrice = 0;
long sumTimeCount = 0;
for (HardOrderCsVo v : sqlList) {
BigDecimal totalProfitPrice = Optional.of(v.getTotalProfitPrice()).orElse(BigDecimal.ZERO);
BigDecimal totalProfitCount = Optional.of(v.getTotalProfitCount()).orElse(BigDecimal.ZERO);
totalProfitPrice = v.getTotalProfitPrice().divide(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
listMap.add(Map.of("col", totalProfitPrice.toString()));
listMap.add(Map.of("col", totalProfitCount.intValue()));
sumTotalPrice += totalProfitPrice.doubleValue();
sumTimeCount += totalProfitCount.longValue();
HardOrderCsVo.Month month = monthTotalList.stream().filter(item -> ObjectUtil.equals(item.getDay(), v.getDay())).findFirst().orElse(null);
if (ObjectUtil.isNotEmpty(month)) {
month.setTotalProfitPrice(month.getTotalProfitPrice() + totalProfitPrice.doubleValue());
month.setTotalProfitCount(month.getTotalProfitCount() + totalProfitCount.longValue());
}
}
listMap.add(Map.of("col", sumTotalPrice));
listMap.add(Map.of("col", sumTimeCount));
return listMap;
}
}
@@ -40,4 +40,15 @@ spring:
# public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2thnpmLBNBxMQ1/LRLu5Ld3FT5D8iT4GZJZMjJqSNbkwbAPKnCgaEvPH3g/0Pn97OnrRqAcU4pZ97wVWQTBhsKS/G3MRrtSC3HmvDwTrCn3URResDeA7C7VS/ujtpCvUgzqmZELf2xFRN7V5Y8bUPooFNK2mViEkF1gsHpMs4OAkC3zAaCY9PyReGaYsNnWLwUSoBJ0fB+6cwgESbjewdxuDVq38kchZ+vovqA5hXMA9nsMEPIF/R3u5qoJ/v3Ii0YJv8odKKyinxAhX0FB97WVVufUFO2AF7cj3aUxgqbWZDOaa4fWwhlSqDp+0tORUclCcUQ/XRHp/KclTDoUjEQIDAQAB
# alipay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnCB+N172m5gxf1Rolfx5LErSiVwQCh0XQdDrVy6aTuVF5EtdqahSHtADyEPsBWudMBhzCfqpoZvfnvH7a+PED6uZ3DoXt7ETh8TmNM5yc+WTnD8pSphQvuHDJ3zMks489KNxiX6sXag71k9H1MXklJGPOUaljHqy/QlRn2ZLT7pFgaFH9LEcVoQBPIOurUn95078h848RFD30jZFW3fakxUGAGVVZaHH62z5OEWOmcA+CwxsEDMa1XMt02RGXgAAq4WOj+BqOGiFmhM8rnrUMchTyvx4umOzGvbF2Y9irN3aBZ5lfg+bzYcJpIOMzlM/V00LnEWzCblJzXNyH4hJQIDAQAB
# callback-url: https://rj4jv5rwqs.by.takin.cc/hard/hard-ali-pay/callback
# # callback-url: https://stgl.pj.gov.cn/api/hard/hard-ali-pay/callback
# # callback-url: https://stgl.pj.gov.cn/api/hard/hard-ali-pay/callback
mini-ali-pay:
app-id: 2021005197658445
merchant-id: 2088570073831141
merchant-account: 1472871899@qq.com
freeze-amount: 100
zm-service-id: 2025122300000000000107601400
private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTYHY0AW2cjbHoOinD8f4CKMKasDmbRw4CEMasG5IzckmeuTqut3GmxxRRls62zlXRVOCDYgnGhzEhD/nMYx0TMBX2mYo+fH9XUMtZMKY+p2rPTXTlPnGfbQ4edUYofR0tq1ug+wHOD5/jxuwO1zPfB7t8dX3gNa4M43fTPK2mPDeo/UiRB45DPjUWvbMX59ltYYMgmAW0TAbXmRAGKFxrmX3HddJK0jSwEpTcHaRV3C6FrYV48vWHEliviVBUsLRIpwv3T3FYZm0a19LcGQtybeThXaaCYrj7Lwoffk8v8DL2g28IAeiFtjjkWbPFKKMCsSe/LVkvdQTuhncuDayTAgMBAAECggEAJvreiMbP7RZ1Nc0cet0op/2L60otEmrqw5UYVzE7rCvQWRD4+nk+sDP7pdDTf/p3LFTcxSNLHp1nWy1UjsCwUgDn7j+SFxDqxXdzMXXyoqO5VndQMcogV2CK2Xd/RPpCm2+1XpDFW3E6gw58JTi6WYU8C6Ev1/uau4H2kYJ9E3h2W0P0PyY+Q9QNHEpG2hLQdiWLHz3xzmSNSDXiknEg/Whew7IMVKNgxg5VVEBTerwCH5Grvn56CKx6acb6JlU+VFsmW3J1tMYLgxVhJWVVAK6NltmxE5apIxTkG3wEOMuuBCZHQ1Lm0rrGKJh8WmYRs6ho5wSjHYG3hyKRm/0TEQKBgQDcDDPyOWw/o9ZqB3N7qxUi63V7wU7X8QL/CmQO4tu/ng/4Drm8QESjk+ib3O3pCC7xwcte/U1Otw3AmSSj1CWvT8a0yLJM9GVOJwZFVyzy6yVFPyn6l4ndRdargyFokM2lgVTgEHo4WSMbLQsA8/KTB3anqo6bYLjqjsBgY49fpQKBgQCrdLMh5ayJOUK9UeBHXr0c/OLDzwoSUVMyNLfX3pIBC21meFxigNMiy+UKpslM2QMH1yyfwsUKv/i7y1kRFj9Go7pYU0HxglfHecllqXPunWJYuSm38x8WWAG/oqcLPGSlJjHYhU6IAkDuHHaW5DKLxr0x2DkZ/c4TcyYal9Ol1wKBgD4Lls4S0On02W1WIoLZT4FkIOE/NWsAAxdEp8fmwY17FQedp1NkT7ZL60efeNm/O/Vg7mYfSCAMz2ziAYnMNMAE34N0H4pBUxtBN6xvkzX/hafL0ptdBTuGCKydsdrZEZM8L2FqY/vlbleoULT5FAnPDe7i0YkQMbO5gpbrG68dAoGAFv+tc7OSREn5CNotwoUTywqlBG0GRdTA2zA1JPDHFvrIbwFgKxpqt/UvwREEWZmWjXuwkbGXqsx7ef1Z8i/QxxH5UhXA97trOOe+OzPSyEQ2R/52eSVUmzOs8F7KF3i/a2PHNesT0Ky0tvv8cFsl6Jf9Eu2VI0ZnWTaN+u04x7sCgYEAlhpr3RSJk2EnLPR3BxKboTxSGsK/2U4xz/WqX96B+lQ5h7NSMJC35vZJ5dm2vHtLcucHaK49YNsJdq+nzhhwxDz+Dd/5rcIp7AcdHqDsVLHYIN7JWxa9QiC3gvrnWsij1DShydOLpGMYveFz0LyRIUDW4CTs55oDFsIR4HdwtM0=
public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk2B2NAFtnI2x6Dopw/H+AijCmrA5m0cOAhDGrBuSM3JJnrk6rrdxpscUUZbOts5V0VTgg2IJxocxIQ/5zGMdEzAV9pmKPnx/V1DLWTCmPqdqz0105T5xn20OHnVGKH0dLatboPsBzg+f48bsDtcz3we7fHV94DWuDON30zytpjw3qP1IkQeOQz41Fr2zF+fZbWGDIJgFtEwG15kQBihca5l9x3XSStI0sBKU3B2kVdwuha2FePL1hxJYr4lQVLC0SKcL909xWGZtGtfS3BkLcm3k4V2mgmK4+y8KH35PL/Ay9oNvCAHohbY45FmzxSijArEnvy1ZL3UE7oZ3Lg2skwIDAQAB
alipay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnCB+N172m5gxf1Rolfx5LErSiVwQCh0XQdDrVy6aTuVF5EtdqahSHtADyEPsBWudMBhzCfqpoZvfnvH7a+PED6uZ3DoXt7ETh8TmNM5yc+WTnD8pSphQvuHDJ3zMks489KNxiX6sXag71k9H1MXklJGPOUaljHqy/QlRn2ZLT7pFgaFH9LEcVoQBPIOurUn95078h848RFD30jZFW3fakxUGAGVVZaHH62z5OEWOmcA+CwxsEDMa1XMt02RGXgAAq4WOj+BqOGiFmhM8rnrUMchTyvx4umOzGvbF2Y9irN3aBZ5lfg+bzYcJpIOMzlM/V00LnEWzCblJzXNyH4hJQIDAQAB
callback-url: https://rj4jv5rwqs.by.takin.cc/hard/hard-ali-pay/callback
# callback-url: https://stgl.pj.gov.cn/api/hard/hard-ali-pay/callback
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bsd.pjcloud.hard.mapper.HardThirdMiOrderMapper">
<sql id="selectA">
select a.id,
a.biz_type,
a.user_id,
a.user_type,
a.auth_id,
a.flow_id,
a.order_id,
a.refund_id,
a.hard_id,
a.out_order_no,
a.third_order_no,
a.create_order_time,
a.pay_order_time,
a.refund_order_time,
a.order_status,
a.deposit_price,
a.order_price,
a.pay_price,
a.refund_price,
a.org_sign_json,
a.org_order_json,
a.create_by,
a.create_time,
a.update_by,
a.update_time,
a.del_flag,
a.tenant_id
</sql>
<sql id="whereA">
a.del_flag = '0'
<if test="dto.bizType != null and dto.bizType != '' ">
and a.biz_type = #{dto.bizType}
</if>
<if test="dto.userId != null ">
and a.user_id = #{dto.userId}
</if>
<if test="dto.hardId != null ">
and a.hard_id = #{dto.hardId}
</if>
<if test="dto.userType != null and dto.userType != '' ">
and a.user_type = #{dto.userType}
</if>
<if test="dto.orderStatus != null and dto.orderStatus != '' ">
and a.order_status = #{dto.orderStatus}
</if>
<if test="dto.createOrderTimeList != null and dto.createOrderTimeList.length == 2">
and a.create_order_time between #{dto.createOrderTimeList[0]} and #{dto.createOrderTimeList[1]}
</if>
<if test="dto.payOrderTimeList != null and dto.payOrderTimeList.length == 2">
and a.pay_order_time between #{dto.payOrderTimeList[0]} and #{dto.payOrderTimeList[1]}
</if>
<if test="dto.refundOrderTimeList != null and dto.refundOrderTimeList.length == 2">
and a.refund_order_time between #{dto.refundOrderTimeList[0]} and #{dto.refundOrderTimeList[1]}
</if>
</sql>
<select id="scopePageJoin" resultType="com.bsd.pjcloud.hard.api.vo.HardThirdMiOrderVo">
<include refid="selectA"/>
from hard_third_mi_order a
<where>
<include refid="whereA"/>
</where>
order by a.create_order_time desc , a.id desc
</select>
</mapper>
@@ -42,10 +42,24 @@
<sql id="whereA">
a.del_flag = '0'
<if test="dto.createTimeStr != null and dto.createTimeStr != '' ">
and DATE_FORMAT(a.create_time, '%Y-%m-%d') = #{dto.createTimeStr}
<choose>
<when test="dto.createTimeType != null and dto.createTimeType != '' ">
<choose>
<when test="dto.createTimeType == '0'.toString() ">
and DATE_FORMAT(a.create_time, '%Y-%m-%d') = #{dto.createTimeStr}
</when>
<when test="dto.createTimeType == '1'.toString() ">
and DATE_FORMAT(a.create_time, '%Y-%m') = #{dto.createTimeStr}
</when>
</choose>
</when>
<otherwise>
and DATE_FORMAT(a.create_time, '%Y-%m-%d') = #{dto.createTimeStr}
</otherwise>
</choose>
</if>
<if test="dto.createTimeList != null and dto.createTimeList.length == 2">
and o.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]}
<if test="dto.createTimeYearStr != null and dto.createTimeYearStr != '' ">
and DATE_FORMAT(a.create_time, '%Y') = #{dto.createTimeYearStr}
</if>
</sql>
@@ -129,7 +143,7 @@
from hard_car a
inner join hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0' and o.hour_type is not null and
o.hour_type not in ('-1')
o.hour_type not in ('-1','null')
<where>
<include refid="whereA"/>
<if test="dto.createTimeList != null and dto.createTimeList.length == 2">
@@ -186,7 +200,77 @@
</if>
</where>
group by DATE_FORMAT(a.create_time, '%Y-%m-%d'), o.hour_type
order by DATE_FORMAT(a.create_time, '%Y-%m-%d') desc, o.hour_type;
order by DATE_FORMAT(a.create_time, '%Y-%m-%d') desc, o.hour_type
</select>
<select id="productTotalByMonth" resultType="com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo">
select DATE_FORMAT(a.create_time, '%Y-%m') as createTimeStr,
o.hour_type,
SUM(a.product_count) as payCount,
SUM(a.total_price) as totalPrice,
count(distinct o.id) as timeCount,
count(distinct o.user_id) as payUserCount
from hard_car a
inner join hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0' and o.hour_type is not null and
o.hour_type not in ('-1','null')
<where>
<include refid="whereA"/>
<if test="dto.createTimeList != null and dto.createTimeList.length == 2">
and o.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]}
</if>
<if test="dto.hourType != null and dto.hourType != '' ">
and o.hour_type = #{dto.hourType}
</if>
<if test="dto.merchantId != null">
and o.merchant_id = #{dto.merchantId}
</if>
<if test="dto.isOfflineOrder != null">
and o.is_offline_order = #{dto.isOfflineOrder}
</if>
<if test="dto.deptIds != null and dto.deptIds.size() != 0">
<choose>
<when test="dto.isInclude != null and dto.isInclude == true">
and o.dept_id IN
</when>
<when test="dto.isInclude != null and dto.isInclude == false">
and o.dept_id NOT IN
</when>
<otherwise>
and o.dept_id IN
</otherwise>
</choose>
<foreach collection="dto.deptIds" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
<if test="dto.merchantDeptIds != null and dto.merchantDeptIds.size() != 0">
and o.merchant_dept_id in
<foreach collection="dto.merchantDeptIds" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
<if test="dto.mchIds != null and dto.mchIds.size() != 0">
and o.merchant_id in
<foreach collection="dto.mchIds" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
<if test="dto.orderStatusCodes != null and dto.orderStatusCodes.size() != 0">
and o.order_status in
<foreach collection="dto.orderStatusCodes" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
<if test="dto.mchTypeCodes != null and dto.mchTypeCodes.size() != 0">
and o.merchant_type in
<foreach collection="dto.mchTypeCodes" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
</where>
group by DATE_FORMAT(a.create_time, '%Y-%m'), o.hour_type
order by DATE_FORMAT(a.create_time, '%Y-%m') desc, o.hour_type
</select>
<select id="proudctQuery" resultType="com.bsd.pjcloud.hard.api.vo.order.HardCarVo">
@@ -216,7 +300,7 @@
</if>
</where>
group by a.product_id
order by SUM(a.product_count) desc
order by a.create_time desc , SUM(a.product_count) desc
</select>
<select id="listByDept" resultType="com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo">
@@ -192,6 +192,9 @@
<if test="dto.payTimeList != null and dto.payTimeList.length == 2">
and a.pay_time between #{dto.payTimeList[0]} and #{dto.payTimeList[1]}
</if>
<if test="dto.payTimeYearStr != null and dto.payTimeYearStr != '' ">
and DATE_FORMAT(a.pay_time, '%Y') = #{dto.payTimeYearStr}
</if>
</sql>
<sql id="pageList">
@@ -223,6 +226,49 @@
order by a.create_time desc, a.user_id desc
</sql>
<select id="selectOrderMerchIds" resultType="java.lang.Long">
select distinct (total.merchantId)
from (select a.merchant_id as merchantId, a.merchant_type as merchantType, a.create_time as createTime
from hard_order a
where a.del_flag = '0'
and a.merchant_id is not null
and a.merchant_type is not null
<if test="dto.createTimeList != null and dto.createTimeList.length == 2">
and a.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]}
</if>
<if test="dto.payTimeYearStr != null and dto.payTimeYearStr != '' ">
and DATE_FORMAT(a.pay_time, '%Y') = #{dto.payTimeYearStr}
</if>
union all
select o.merchant_id as merchantId, o.merchant_type as merchantType, a.create_time
from hard_after_sale a
left join hard_order o on o.id = a.order_id
where a.del_flag = '0'
and o.merchant_id is not null
and o.merchant_type is not null
<if test="dto.createTimeList != null and dto.createTimeList.length == 2">
and a.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]}
</if>
<if test="dto.payTimeYearStr != null and dto.payTimeYearStr != '' ">
and DATE_FORMAT(a.refund_time, '%Y') = #{dto.payTimeYearStr}
</if>
) total
<where>
<if test="dto.merchIds != null and dto.merchIds.size() != 0">
and total.merchantId in
<foreach collection="dto.merchIds" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
<if test="dto.merchTypes != null and dto.merchTypes.size() != 0">
and total.merchantType in
<foreach collection="dto.merchTypes" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
</where>
</select>
<select id="scopePageList" resultType="com.bsd.pjcloud.hard.api.vo.order.HardOrderVo">
<include refid="pageList"/>
</select>
@@ -367,6 +413,40 @@
ELSE 5 END
</select>
<select id="listRefundCsByMonth" resultType="com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo">
select
DATE_FORMAT(r.audit_time, '%Y-%m') as day,
a.merchant_id,
sum(ifnull(r.refund_price, 0)) as totalPayPrice,
count(0) as totalPayCount
from hard_after_sale r
inner join hard_order a on a.id = r.order_id and r.del_flag = '0'
<where>
<include refid="whereA"/>
and a.merchant_id is not null
<if test="dto.refundTimeList != null and dto.refundTimeList.length == 2">
and r.audit_time between #{dto.refundTimeList[0]} and #{dto.refundTimeList[1]}
</if>
<if test="dto.auditTimeYearStr != null and dto.auditTimeYearStr != '' ">
and DATE_FORMAT(r.audit_time, '%Y') = #{dto.auditTimeYearStr}
</if>
<if test="dto.refundStatusCodes != null and dto.refundStatusCodes.size() != 0">
and r.status in
<foreach collection="dto.refundStatusCodes" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
</where>
group by a.merchant_id,DATE_FORMAT(r.audit_time, '%Y-%m')
order by DATE_FORMAT(r.audit_time, '%Y-%m'),
CASE a.merchant_type
WHEN 1 THEN 1
WHEN 3 THEN 2
WHEN 0 THEN 3
WHEN 2 THEN 4
ELSE 5 END
</select>
<select id="listCsByDay" resultType="com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo">
select a.merchant_id,
DATE_FORMAT(a.create_time, '%Y-%m-%d') as day,
@@ -380,6 +460,20 @@
order by DATE_FORMAT(a.create_time, '%Y-%m-%d') desc, a.merchant_id desc
</select>
<select id="pageCsByMonth" resultType="com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo">
select a.merchant_id,
DATE_FORMAT(a.pay_time, '%Y-%m') as day,
sum(a.pay_price) as totalPayPrice,
count(0) as totalPayCount
from hard_order a
<where>
<include refid="whereA"/>
and a.merchant_id is not null
</where>
group by a.merchant_id, DATE_FORMAT(a.pay_time, '%Y-%m')
order by a.merchant_id desc, DATE_FORMAT(a.pay_time, '%Y-%m') desc
</select>
<select id="listCsTotal" resultType="com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo">
select a.merchant_id,
sum(a.pay_price) as totalPayPrice,
@@ -0,0 +1,33 @@
package com.bsd.pjcloud.integrated.constant.appmodule;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* App平台
*/
@Getter
@AllArgsConstructor
public enum AppPlatformEnum {
ANDROID("1", "android"),
IOS("2", "ios"),
;
private final String code;
private final String desc;
public static AppPlatformEnum valueOfByType(String code) {
return Arrays.stream(AppPlatformEnum.values())
.filter(v -> ObjectUtil.equal(v.getCode(), code))
.findFirst().orElse(null);
}
public static AppPlatformEnum descOf(String description) {
return Arrays.stream(AppPlatformEnum.values())
.filter(v -> ObjectUtil.equal(v.getDesc(), description))
.findFirst().orElse(null);
}
}
@@ -0,0 +1,33 @@
package com.bsd.pjcloud.integrated.constant.appmodule;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* App版本状态
*/
@Getter
@AllArgsConstructor
public enum AppVersionStatusEnum {
PUBLISHED("1", "已发布"),
UNPUBLISHED("2", "未发布"),
OFF_SHELF("3", "已下架"),
;
private final String code;
private final String desc;
public static AppVersionStatusEnum valueOfByType(String code) {
return Arrays.stream(AppVersionStatusEnum.values())
.filter(v -> ObjectUtil.equal(v.getCode(), code))
.findFirst().orElse(null);
}
public static AppVersionStatusEnum descOf(String description) {
return Arrays.stream(AppVersionStatusEnum.values())
.filter(v -> ObjectUtil.equal(v.getDesc(), description))
.findFirst().orElse(null);
}
}
@@ -0,0 +1,94 @@
package com.bsd.pjcloud.integrated.controller.appmodule;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.integrated.dto.appmodule.AppVersionDto;
import com.bsd.pjcloud.integrated.entity.app.AppVersionEntity;
import com.bsd.pjcloud.integrated.service.AppVersionService;
import com.bsd.pjcloud.integrated.vo.appmodule.AppVersionVo;
import org.springframework.security.access.prepost.PreAuthorize;
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.*;
/**
* app版本控制表
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/app-version")
@Tag(description = "app-version", name = "app版本控制表管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class AppVersionController {
private final AppVersionService appVersionService;
/* ************************************* start 设备端 start ************************************* */
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/ad/page")
public R<Page<AppVersionVo>> hardPage(@ParameterObject Page page, @ParameterObject AppVersionDto dto) {
return R.ok(appVersionService.pageList(page, dto));
}
/* ************************************* end 设备端 end ************************************* */
/**
* 分页查询
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('integrated_appVersion_view')")
public R<Page<AppVersionVo>> getAppVersionPage(@ParameterObject Page page, @ParameterObject AppVersionDto dto) {
return R.ok(appVersionService.pageList(page, dto));
}
/**
* 通过id查询app版本控制表
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('integrated_appVersion_view')")
public R getById(@PathVariable("id") Long id) {
return R.ok(appVersionService.getById(id));
}
/**
* 新增app版本控制表
*/
@Operation(summary = "新增app版本控制表", description = "新增app版本控制表")
@SysLog("新增app版本控制表")
@PostMapping
@PreAuthorize("@pms.hasPermission('integrated_appVersion_add')")
public R save(@RequestBody AppVersionEntity appVersion) {
return R.ok(appVersionService.save(appVersion));
}
/**
* 修改app版本控制表
*/
@Operation(summary = "修改app版本控制表", description = "修改app版本控制表")
@SysLog("修改app版本控制表")
@PutMapping
@PreAuthorize("@pms.hasPermission('integrated_appVersion_edit')")
public R updateById(@RequestBody AppVersionEntity appVersion) {
return R.ok(appVersionService.updateById(appVersion));
}
/**
* 通过id删除app版本控制表
*/
@Operation(summary = "通过id删除app版本控制表", description = "通过id删除app版本控制表")
@SysLog("通过id删除app版本控制表")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('integrated_appVersion_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appVersionService.removeBatchByIds(CollUtil.toList(ids)));
}
}
@@ -0,0 +1,8 @@
package com.bsd.pjcloud.integrated.dto.appmodule;
import com.bsd.pjcloud.integrated.entity.app.AppVersionEntity;
import lombok.Data;
@Data
public class AppVersionDto extends AppVersionEntity {
}
@@ -0,0 +1,124 @@
package com.bsd.pjcloud.integrated.entity.app;
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;
/**
* app版本控制表
*/
@Data
@TenantTable
@TableName("app_version")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "app版本控制表")
public class AppVersionEntity extends Model<AppVersionEntity> {
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键ID")
private Long id;
/**
* app唯一编码
*/
@Schema(description = "app唯一编码")
private String appUniqueCode;
/**
* 平台类型(android、ios)
*/
@Schema(description = "平台类型(android、ios)")
private String platform;
/**
* 内部版本号(用于比较大小)
*/
@Schema(description = "内部版本号(用于比较大小)")
private Integer versionCode;
/**
* 展示版本号(字符串)
*/
@Schema(description = "展示版本号(字符串)")
private String versionName;
/**
* 更新内容/更新日志
*/
@Schema(description = "更新内容/更新日志")
private String updateContent;
/**
* 安装包下载地址(wgt、apk)
*/
@Schema(description = "安装包下载地址(wgt、apk)")
private String downloadUrl;
/**
* 是否强制更新
*/
@Schema(description = "是否强制更新")
private String isForce;
/**
* 是否静默更新(WGT用)
*/
@Schema(description = "是否静默更新(WGT用)")
private String isSilent;
/**
* 状态(已发布、未发布、已下架)
*/
@Schema(description = "状态(已发布、未发布、已下架)")
private String status;
/**
* 创建者
*/
@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;
/**
* 是否删除(0=正常 1=删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "是否删除(0=正常 1=删除)")
private String delFlag;
/**
* 租户编号
*/
@Schema(description = "租户编号")
private Long tenantId;
}
@@ -0,0 +1,16 @@
package com.bsd.pjcloud.integrated.mapper.appmodule;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.integrated.dto.appmodule.AppVersionDto;
import com.bsd.pjcloud.integrated.entity.app.AppVersionEntity;
import com.bsd.pjcloud.integrated.vo.appmodule.AppVersionVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface AppVersionMapper extends PjcloudBaseMapper<AppVersionEntity> {
Page<AppVersionVo> pagList(Page page, @Param("dto") AppVersionDto dto);
}
@@ -0,0 +1,15 @@
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.appmodule.AppVersionDto;
import com.bsd.pjcloud.integrated.entity.app.AppVersionEntity;
import com.bsd.pjcloud.integrated.vo.appmodule.AppVersionVo;
public interface AppVersionService extends IService<AppVersionEntity> {
/**
* 分页查询
*/
Page<AppVersionVo> pageList(Page page, AppVersionDto dto);
}
@@ -0,0 +1,26 @@
package com.bsd.pjcloud.integrated.service.impl.appmodule;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.integrated.dto.appmodule.AppVersionDto;
import com.bsd.pjcloud.integrated.entity.app.AppVersionEntity;
import com.bsd.pjcloud.integrated.mapper.appmodule.AppVersionMapper;
import com.bsd.pjcloud.integrated.service.AppVersionService;
import com.bsd.pjcloud.integrated.vo.appmodule.AppVersionVo;
import org.springframework.stereotype.Service;
/**
* app版本控制表
*/
@Service
public class AppVersionServiceImpl extends ServiceImpl<AppVersionMapper, AppVersionEntity> implements AppVersionService {
/**
* 分页查询
*/
@Override
public Page<AppVersionVo> pageList(Page page, AppVersionDto dto) {
return baseMapper.pagList(page, dto);
}
}
@@ -0,0 +1,8 @@
package com.bsd.pjcloud.integrated.vo.appmodule;
import com.bsd.pjcloud.integrated.entity.app.AppVersionEntity;
import lombok.Data;
@Data
public class AppVersionVo extends AppVersionEntity {
}
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bsd.pjcloud.integrated.mapper.appmodule.AppVersionMapper">
<sql id="selectA">
select a.id,
a.app_unique_code,
a.platform,
a.version_code,
a.version_name,
a.update_content,
a.download_url,
a.is_force,
a.is_silent,
a.status,
a.create_by,
a.create_time,
a.update_by,
a.update_time,
a.del_flag,
a.tenant_id
</sql>
<sql id="whereA">
a.del_flag = '0'
<if test="dto.appUniqueCode != null and dto.appUniqueCode != '' ">
and a.app_unique_code LIKE CONCAT('%',#{dto.appUniqueCode},'%')
</if>
<if test="dto.status != null and dto.status != '' ">
and a.status = #{dto.status}
</if>
<if test="dto.platform != null and dto.platform != '' ">
and a.platform = #{dto.platform}
</if>
</sql>
<select id="pagList" resultType="com.bsd.pjcloud.integrated.vo.appmodule.AppVersionVo">
<include refid="selectA"/>
from app_version a
<where>
<include refid="whereA"/>
</where>
</select>
</mapper>
@@ -0,0 +1,31 @@
package com.bsd.pjcloud.admin.api.constant;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 用户在编情况
*/
@AllArgsConstructor
@Getter
public enum UserStaffingTypeEnum {
STAFFING("1", "在编"),
NONE_STAFFING("2", "非编"),
;
private final String type;
private final String description;
public static UserStaffingTypeEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().orElse(null);
}
public static UserStaffingTypeEnum valueOfByDescription(String description) {
if (ObjectUtil.isEmpty(description)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(description, v.getDescription())).findFirst().orElse(null);
}
}
@@ -0,0 +1,27 @@
package com.bsd.pjcloud.admin.api.constant.visitor;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 访客类型
*/
@AllArgsConstructor
@Getter
public enum VisitorBizEnum {
WECHAT("10", "微信小程序"),
ALIPAY("20", "支付宝小程序"),
;
private final String type;
private final String description;
public static VisitorBizEnum valueOfByType(String type) {
if (ObjectUtil.isEmpty(type)) return null;
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get();
}
}
@@ -0,0 +1,16 @@
package com.bsd.pjcloud.admin.api.dto;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
@Data
public class SysAppUserModifyDto {
private Long userId;
@NotNull(message = "生日不能为空")
private LocalDate birthday;
}
@@ -31,6 +31,7 @@ import org.javers.core.metamodel.annotation.DiffInclude;
import org.javers.core.metamodel.annotation.PropertyName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
@@ -160,6 +161,12 @@ public class SysUser extends Model<SysUser> implements Serializable {
@Schema(description = "头像地址")
private String avatar;
/**
* 生日
*/
@Schema(description = "生日")
private LocalDate birthday;
/**
* 部门ID
*/
@@ -240,9 +247,21 @@ public class SysUser extends Model<SysUser> implements Serializable {
@Schema(description = "员工浙政钉编码")
private String dingtalkEmployeeCode;
/**
* 员工所属系统类型
*/
@Schema(description = "员工所属系统类型")
private String systemType;
/**
* 是否为全局人脸
*/
@Schema(description = "是否为全局人脸")
private String isGlobalFace;
/**
* 编制类型
*/
@Schema(description = "编制类型")
private String staffingType;
}
@@ -48,4 +48,11 @@ public class UserExcelFaceVo {
*/
@ExcelProperty("用户性别")
private String sex;
/**
* 编制
*/
@ExcelProperty("编制")
private String staffingType;
}
@@ -92,6 +92,14 @@ public class UserExcelVO implements Serializable {
@ExcelProperty("岗位名称")
private String postNameList;
/**
* 编制
*/
@ExcelProperty("编制")
private String staffingType;
private String staffingTypeParse;
/**
* 锁定标记
*/
@@ -241,4 +241,9 @@ public class UserVO implements BaseFacesInterface, Serializable {
* 商户相关
*/
private String merchantName;
/**
* 编制类型
*/
private String staffingType;
}
@@ -0,0 +1,45 @@
package com.bsd.pjcloud.admin.api.vo.total;
import lombok.Data;
import java.util.List;
@Data
public class UserStaffingTotalVo {
/**
* 部门id
*/
private Long deptId;
/**
* 部门名
*/
private String deptName;
/**
* 部门总人数
*/
private Long deptTotalPerson = 0L;
/**
* 在编人数
*/
private Long staffingPerson = 0L;
/**
* 非在编人数
*/
private Long noneStaffingPerson = 0L;
/**
* 统计人数
*/
private Long totalPerson = 0L;
/**
* 未填写人数
*/
private Long fillInPerson = 0L;
}
@@ -26,12 +26,12 @@ public class RegisterController {
private final SysUserService userService;
/**
* 注册用户
*
* @param userDto 用户信息
* @return success/false
*/
// /**
// * 注册用户
// *
// * @param userDto 用户信息
// * @return success/false
// */
// @SysLog("注册用户")
// @PostMapping("/user")
// @ConditionalOnProperty(name = "register.user", matchIfMissing = true)
@@ -39,6 +39,14 @@ public class RegisterController {
// return userService.registerUser(userDto);
// }
/**
* 注册普通用户
*/
@SysLog("注册用户")
@PostMapping("/default-user")
public R<Boolean> registerDefaultUser(@RequestBody UserDTO userDto) {
return userService.registerDefaultUser(userDto);
}
/**
@@ -25,6 +25,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.SysAppUserModifyDto;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.UserDeptSimpleInfo;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
@@ -46,6 +47,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;
@@ -66,6 +68,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -95,6 +98,7 @@ public class SysUserController {
private final SysRoleService sysRoleService;
private final SysUserRoleService sysUserRoleService;
/* ************************************* start 回调 start ************************************* */
@Inner(value = false)
@@ -105,6 +109,16 @@ public class SysUserController {
/* ************************************* end 回调 end ************************************* */
/* ************************************* start app start ************************************* */
@PostMapping("/app/modify")
public R<Boolean> appModify(@Validated @RequestBody SysAppUserModifyDto dto) {
PjcloudUser user = SecurityUtils.getUser();
dto.setUserId(user.getId());
return R.ok(userService.appModify(dto));
}
/* ************************************* end app end ************************************* */
/**
* 获取指定用户全部信息
*
@@ -133,16 +147,16 @@ public class SysUserController {
@GetMapping("/get-name-or-mobile")
public R<List<UserDeptSimpleInfo>> getUserByNameOrMobile(@RequestParam("keyword") String keyword) {
List<SysUser> users = userService.list(
Wrappers.<SysUser>query().lambda()
.eq(SysUser::getName, keyword)
.or()
.eq(SysUser::getPhone, keyword)
Wrappers.<SysUser>query().lambda()
.eq(SysUser::getName, keyword)
.or()
.eq(SysUser::getPhone, keyword)
);
if (CollectionUtils.isEmpty(users)) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, keyword));
}
Map<Long, SysDept> deptListByDeptIds = sysDeptService.getDeptListByDeptIds(
users.stream().map(SysUser::getDeptId).collect(Collectors.toList())
users.stream().map(SysUser::getDeptId).collect(Collectors.toList())
);
List<UserDeptSimpleInfo> userDeptSimpleInfos = users.stream().map(user -> {
UserDeptSimpleInfo userDeptSimpleInfo = new UserDeptSimpleInfo();
@@ -419,14 +433,15 @@ public class SysUserController {
/**
* 根据部门id查询用户列表
*
* @param deptId
* @return
*/
// @Inner
@GetMapping("/getUserIdListByDeptId")
public R<List<SimpleUserListVO>> getUserIdListByDeptId(@RequestParam("deptId")Long deptId,
@RequestParam(value = "name",required = false) String name) {
return R.ok(userService.listUserIdByDeptId(deptId,name));
public R<List<SimpleUserListVO>> getUserIdListByDeptId(@RequestParam("deptId") Long deptId,
@RequestParam(value = "name", required = false) String name) {
return R.ok(userService.listUserIdByDeptId(deptId, name));
}
/**
@@ -497,7 +512,7 @@ public class SysUserController {
@Schema(description = "根据ids获取用户map")
public R<Map<Long, SysUser>> getUserMap(@RequestParam(value = "userIds") Set<Long> userIds) {
LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
sysUserLambdaQueryWrapper.in(SysUser::getUserId, userIds);
sysUserLambdaQueryWrapper.in(ObjectUtil.isNotEmpty(userIds), SysUser::getUserId, userIds);
List<SysUser> list = userService.list(sysUserLambdaQueryWrapper);
Map<Long, SysUser> userMap = list.stream().collect(Collectors.toMap(SysUser::getUserId, user -> user));
return R.ok(userMap);
@@ -544,7 +559,7 @@ public class SysUserController {
}
List<SysUserRole> list = sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getRoleId, sysRole.getRoleId()));
List<Long> userIds = list.stream().map(sysUserRole -> sysUserRole.getUserId()).collect(Collectors.toList());
List<SysUser> listData = userService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, userIds));
List<SysUser> listData = userService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, userIds));
//转换成vo,只返回id+手机号+姓名,安全考虑
List<UserSimpleVo> userVOList = listData.stream().map(sysUser -> {
UserSimpleVo userVO = new UserSimpleVo();
@@ -0,0 +1,41 @@
package com.bsd.pjcloud.admin.controller.total;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.vo.total.UserStaffingTotalVo;
import com.bsd.pjcloud.admin.service.SysUserTotalService;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import io.swagger.v3.oas.annotations.Operation;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 用户相关统计
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/user/total")
@Tag(description = "connect", name = "用户相关统计")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysUserTotalController {
private final SysUserTotalService sysUserTotalService;
@Operation(summary = "用户在/非编人员统计", description = "用户在/非编人员统计")
@PostMapping("/staffing-total")
public R<List<UserStaffingTotalVo>> staffingTotal(@RequestBody UserDTO dto) {
DataScope dataScope = null;
return R.ok(sysUserTotalService.staffingTotal(dto, dataScope));
}
}
@@ -24,6 +24,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.vo.UserVO;
import com.bsd.pjcloud.admin.api.vo.total.UserStaffingTotalVo;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import org.apache.ibatis.annotations.Mapper;
@@ -42,35 +43,43 @@ import java.util.List;
@Mapper
public interface SysUserMapper extends PjcloudBaseMapper<SysUser> {
/**
* 通过用户名查询用户信息(含有角色信息)
* @param username 用户名
* @return userVo
*/
UserVO getUserVoByUsername(String username);
/**
* 通过用户名查询用户信息(含有角色信息)
*
* @param username 用户名
* @return userVo
*/
UserVO getUserVoByUsername(String username);
/**
* 分页查询用户信息(含角色)
* @param page 分页
* @param userDTO 查询参数
* @param dataScope
* @return list
*/
IPage<UserVO> getUserVosPage(Page page, @Param("query") UserDTO userDTO, DataScope dataScope);
/**
* 分页查询用户信息(含角色)
*
* @param page 分页
* @param userDTO 查询参数
* @param dataScope
* @return list
*/
IPage<UserVO> getUserVosPage(Page page, @Param("query") UserDTO userDTO, DataScope dataScope);
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return userVo
*/
UserVO getUserVoById(Long id);
/**
* 通过ID查询用户信息
*
* @param id 用户ID
* @return userVo
*/
UserVO getUserVoById(Long id);
/**
* 查询用户列表
* @param userDTO 查询条件
* @param dataScope 数据权限声明
* @return
*/
List<UserVO> selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope);
/**
* 查询用户列表
*
* @param userDTO 查询条件
* @param dataScope 数据权限声明
* @return
*/
List<UserVO> selectVoListByScope(@Param("query") UserDTO userDTO, @Param("ids") Long[] ids, DataScope dataScope);
/**
* 用户在/非编人员统计
*/
List<UserStaffingTotalVo> staffingListByDept(@Param("dto") UserDTO dto, DataScope dataScope);
}
@@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.admin.api.dto.SysAppUserModifyDto;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.entity.SysUser;
@@ -84,6 +85,11 @@ public interface SysUserService extends IService<SysUser> {
*/
Boolean updateUser(UserDTO userDto);
/**
* app更新用户
*/
Boolean appModify(SysAppUserModifyDto dto);
/**
* 通过ID查询用户信息
*
@@ -136,6 +142,11 @@ public interface SysUserService extends IService<SysUser> {
*/
R<Boolean> registerUser(UserDTO userDto);
/**
* 注册普通用户
*/
R<Boolean> registerDefaultUser(UserDTO userDto);
/**
* 锁定用户
*
@@ -0,0 +1,16 @@
package com.bsd.pjcloud.admin.service;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.vo.total.UserStaffingTotalVo;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import java.util.List;
public interface SysUserTotalService {
/**
* 用户在/非编人员统计
*/
List<UserStaffingTotalVo> staffingTotal(UserDTO dto, DataScope dataScope);
}
@@ -19,6 +19,7 @@
package com.bsd.pjcloud.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ArrayUtil;
@@ -33,7 +34,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.admin.api.constant.UserStaffingTypeEnum;
import com.bsd.pjcloud.admin.api.constant.UserStateEnum;
import com.bsd.pjcloud.admin.api.dto.SysAppUserModifyDto;
import com.bsd.pjcloud.admin.api.dto.SysUserFaceDto;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
@@ -48,32 +51,23 @@ import com.bsd.pjcloud.admin.service.*;
import com.bsd.pjcloud.admin.utils.excel.ExcelTool;
import com.bsd.pjcloud.admin.utils.flow.FlowUtil;
import com.bsd.pjcloud.admin.utils.flow.dto.UserApplyFlowDto;
import com.bsd.pjcloud.admin.utils.flow.dto.UserFaceApplyFlowDto;
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.MerchantTypeEnum;
import com.bsd.pjcloud.common.core.exception.ErrorCodes;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.MsgUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.resolver.ParamResolver;
import com.bsd.pjcloud.common.data.tenant.TenantContextHolder;
import com.bsd.pjcloud.common.excel.vo.ErrorMessage;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.flow.task.dto.TaskDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.excel.WalletRechargeExcelDto;
import com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity;
import com.bsd.pjcloud.wallet.api.feign.RemoteMchService;
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService;
import com.bsd.pjcloud.wallet.api.utils.WalletDataUtil;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplyVo;
import cn.hutool.extra.spring.SpringUtil;
import lombok.AllArgsConstructor;
@@ -84,7 +78,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.annotation.Lazy;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -435,6 +428,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return Boolean.TRUE;
}
@Override
public Boolean appModify(SysAppUserModifyDto dto) {
SysUser updateObj = BeanUtil.toBean(dto, SysUser.class);
return baseMapper.updateById(updateObj) > 0;
}
/**
* 查询上级部门的用户信息
*
@@ -473,6 +472,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
excelVO.setRoleNameList(roleNameList);
String postNameList = userVO.getPostList().stream().map(SysPost::getPostName).collect(Collectors.joining(StrUtil.COMMA));
excelVO.setPostNameList(postNameList);
if (ObjectUtil.isNotEmpty(userVO.getStaffingType())) {
UserStaffingTypeEnum staffingTypeEnum = UserStaffingTypeEnum.valueOfByType(userVO.getStaffingType());
if (ObjectUtil.isNotEmpty(staffingTypeEnum)) {
excelVO.setStaffingType(staffingTypeEnum.getDescription());
}
}
return excelVO;
}).collect(Collectors.toList());
return userExcelVOList;
@@ -526,6 +531,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
List<String> postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA);
List<SysPost> postCollList = postList.stream().filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name))).collect(Collectors.toList());
// 判断输入的编制是否合法
if (ObjectUtil.isEmpty(excel.getStaffingType())) {
errorMsg.add(MsgUtils.getMessage("编制不存在", excel.getStaffingType()));
} else {
UserStaffingTypeEnum staffingTypeEnum = UserStaffingTypeEnum.valueOfByDescription(excel.getStaffingType());
if (ObjectUtil.isEmpty(staffingTypeEnum)) {
errorMsg.add(MsgUtils.getMessage("编制选择错误,请选择<在编>和<非编>", excel.getStaffingType()));
} else {
excel.setStaffingTypeParse(staffingTypeEnum.getType());
}
}
if (postCollList.size() != postNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
}
@@ -620,7 +637,21 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
}
// 判断输入的编制是否合法
String staffingType = null;
if (ObjectUtil.isEmpty(v.getStaffingType())) {
errorMsg.add("请选择编制");
} else {
UserStaffingTypeEnum staffingTypeEnum = UserStaffingTypeEnum.valueOfByDescription(v.getStaffingType());
if (ObjectUtil.isEmpty(staffingTypeEnum)) {
errorMsg.add("编制选择错误,请选择<在编>和<非编>");
} else {
staffingType = staffingTypeEnum.getType();
}
}
if (CollUtil.isEmpty(errorMsg)) {
v.setStaffingType(staffingType);
insertExcelUser(v, deptId, roleIds, face);
} else {
errorMessageList.add(new ErrorMessage(v.getLineNum(), errorMsg));
@@ -648,6 +679,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
userDTO.setLockFlag(excel.getLockFlag());
userDTO.setStaffingType(excel.getStaffingTypeParse());
// 批量导入初始密码为手机号
userDTO.setPasswordModifyTime(LocalDateTime.now());
userDTO.setPassword(userDTO.getPhone());
@@ -671,6 +703,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
userDTO.setNickname(excel.getName().replaceAll("\\s+", ""));
userDTO.setPhone(excel.getMobile().replaceAll("\\s+", ""));
userDTO.setDeptId(deptId);
userDTO.setStaffingType(excel.getStaffingType());
// 批量导入初始密码为手机号
userDTO.setPasswordModifyTime(LocalDateTime.now());
userDTO.setPassword(userDTO.getPhone().replaceAll("\\s+", ""));
@@ -728,6 +761,71 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return R.ok(true);
}
/**
* 注册用户 赋予用户默认角色
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> registerDefaultUser(UserDTO userDto) {
userDto.setPhone(userDto.getUsername());
// 判断用户名是否存在
boolean usernameExists = this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
if (usernameExists) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message);
}
// 判断手机号是否存在
boolean phoneExists = this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, userDto.getPhone()));
if (phoneExists) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone());
return R.failed(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.<SysRole>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 R.ok(null);
}
/**
* 锁定用户
*
@@ -0,0 +1,94 @@
package com.bsd.pjcloud.admin.service.impl.total;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.collection.IterableIter;
import cn.hutool.core.util.ObjectUtil;
import com.bsd.pjcloud.admin.api.dto.DeptAllListDto;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.entity.SysDept;
import com.bsd.pjcloud.admin.api.vo.total.UserStaffingTotalVo;
import com.bsd.pjcloud.admin.mapper.SysDeptMapper;
import com.bsd.pjcloud.admin.mapper.SysUserMapper;
import com.bsd.pjcloud.admin.service.SysDeptService;
import com.bsd.pjcloud.admin.service.SysUserTotalService;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserTotalServiceImpl implements SysUserTotalService {
private final SysUserMapper sysUserMapper;
private final SysDeptMapper sysDeptMapper;
private final SysDeptService sysDeptService;
/**
* 用户在/非编人员统计
*/
@Override
public List<UserStaffingTotalVo> staffingTotal(UserDTO dto, DataScope dataScope) {
// 查询部门
DeptAllListDto deptDto = new DeptAllListDto();
deptDto.setIsInclude(dto.getIsInclude());
if (ObjectUtil.isNotEmpty(dto.getDeptId())) {
deptDto.setDeptId(dto.getDeptId());
}
if (ObjectUtil.isNotEmpty(dto.getDeptIds())) {
deptDto.setDeptId(null);
deptDto.setDeptIds(dto.getDeptIds());
}
List<SysDept> deptList = sysDeptMapper.allList(deptDto);
if (ObjectUtil.isEmpty(deptList)) return null;
List<UserStaffingTotalVo> disposeDeptList = deptList.stream().map(item -> {
UserStaffingTotalVo entity = new UserStaffingTotalVo();
entity.setDeptId(item.getDeptId());
entity.setDeptName(item.getName());
return entity;
}).toList();
dto.setProcessStatus(TaskCheckStatusEnum.RESULT.getCode());
List<UserStaffingTotalVo> list = sysUserMapper.staffingListByDept(dto, dataScope);
// 查询部门名字
disposeStaffingTotal(list);
Map<Long, UserStaffingTotalVo> sqlMap = IterUtil.toMap(list, UserStaffingTotalVo::getDeptId);
for (UserStaffingTotalVo vo : disposeDeptList) {
UserStaffingTotalVo targetMap = sqlMap.get(vo.getDeptId());
if (ObjectUtil.isEmpty(targetMap)) continue;
vo.setDeptTotalPerson(targetMap.getDeptTotalPerson());
vo.setStaffingPerson(targetMap.getStaffingPerson());
vo.setNoneStaffingPerson(targetMap.getNoneStaffingPerson());
vo.setTotalPerson(targetMap.getTotalPerson());
vo.setFillInPerson(targetMap.getFillInPerson());
}
return disposeDeptList;
}
private void disposeStaffingTotal(List<UserStaffingTotalVo> list) {
if (ObjectUtil.isEmpty(list)) return;
List<Long> dpetIdList = list.stream().map(UserStaffingTotalVo::getDeptId).distinct().filter(ObjectUtil::isNotEmpty).toList();
if (ObjectUtil.isNotEmpty(dpetIdList)) {
Map<Long, SysDept> deptMaps = sysDeptService.getDeptListByDeptIds(dpetIdList);
if (ObjectUtil.isNotEmpty(deptMaps)) {
for (UserStaffingTotalVo v : list) {
SysDept sysDept = deptMaps.get(v.getDeptId());
if (ObjectUtil.isEmpty(sysDept)) continue;
v.setDeptName(sysDept.getName());
}
}
}
}
}
Loaded 100 of 182 files, more files were not shown because too many files have changed in this diff. Show more