Преглед на файлове

feat: 积分充值联调

李学松 преди 2 години
родител
ревизия
4af0ae6770
променени са 38 файла, в които са добавени 3227 реда и са изтрити 18 реда
  1. 92 0
      db/v2.0/230628.sql
  2. 5 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/CacheConstants.java
  3. 2 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/HnqzAdminApplication.java
  4. 0 1
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmContractController.java
  5. 30 6
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/enums/DeptLevelEnum.java
  6. 23 11
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/enums/ScorePackageStatusEnum.java
  7. 172 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/controller/SysDeptInvoiceController.java
  8. 191 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/controller/SysDeptRechargeController.java
  9. 128 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/dto/SysDeptInvoiceRequest.java
  10. 151 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/dto/SysDeptRechargeRequest.java
  11. 103 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptInvoice.java
  12. 77 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptInvoiceRelation.java
  13. 91 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptRecharge.java
  14. 94 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptRechargeRecord.java
  15. 25 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/InvoiceApprovalStatus.java
  16. 43 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/InvoiceStatus.java
  17. 24 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/InvoiceType.java
  18. 24 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/RechargeRecordPackageType.java
  19. 29 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/RechargeRecordType.java
  20. 20 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptInvoiceMapper.java
  21. 58 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptInvoiceRelationMapper.java
  22. 20 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptRechargeMapper.java
  23. 20 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptRechargeRecordMapper.java
  24. 13 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptInvoiceRelationService.java
  25. 78 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptInvoiceService.java
  26. 39 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptRechargeRecordService.java
  27. 42 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptRechargeService.java
  28. 22 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptInvoiceRelationServiceImpl.java
  29. 499 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptInvoiceServiceImpl.java
  30. 232 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptRechargeRecordServiceImpl.java
  31. 251 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptRechargeServiceImpl.java
  32. 98 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptInvoiceRelationVO.java
  33. 113 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptInvoiceVO.java
  34. 69 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeForParkVO.java
  35. 89 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeRecordForDeptVO.java
  36. 95 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeRecordVO.java
  37. 85 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeVO.java
  38. 80 0
      hnqz-upms/hnqz-upms-biz/src/main/resources/mapper/SysDeptInvoiceRelationMapper.xml

+ 92 - 0
db/v2.0/230628.sql

@@ -0,0 +1,92 @@
+create table sys_dept_recharge
+(
+    id              int auto_increment comment '主键id'
+        primary key,
+    dept_id         int                                      null comment '组织机构ID',
+    score           int            default 0                 not null comment '积分余额',
+    balance         decimal(10, 2) default 0.00              not null comment '余额(元)',
+    permissions     varchar(64)                              null comment '权限,多个逗号分隔',
+    service_charge  decimal(5, 2)  default 0.00              not null comment '服务费率',
+    overdraw_amount decimal(10, 2) default 0.00              not null comment '可透支金额',
+    overdraw_score  int            default 0                 not null comment '可透支积分',
+    del_flag        varchar(10)    default '0'               not null comment '是否删除',
+    create_time     datetime       default CURRENT_TIMESTAMP null comment '创建时间',
+    create_user     int                                      null comment '创建人',
+    update_time     datetime                                 null comment '更新时间',
+    update_user     int                                      null comment '更新人',
+    version         int            default 0                 null,
+    constraint sys_dept_recharge_dept_id_uindex
+        unique (dept_id)
+)
+    comment '积分充值表' charset = utf8mb4;
+
+create table sys_dept_recharge_record
+(
+    id               int auto_increment comment '主键id'
+        primary key,
+    recharge_id      int                                      null comment '积分充值表ID',
+    dept_id          int                                      null comment '组织机构ID',
+    relation_dept_id int                                      null comment '关联组织机构ID(关联操作对象)',
+    change_score     int                                      not null comment '充值积分',
+    change_amount    decimal(10, 2) default 0.00              not null comment '充值金额(元)',
+    type             char(15)                                 not null comment '操作类型',
+    current_score    int                                      not null comment '充值后积分余额',
+    current_balance  decimal(10, 2) default 0.00              not null comment '充值后积分余额(元)',
+    package_id       int                                      null comment '积分包id',
+    package_type     varchar(32)                              null comment '积分包类型',
+    del_flag         varchar(10)    default '0'               not null comment '是否删除',
+    create_time      datetime       default CURRENT_TIMESTAMP null comment '创建时间',
+    create_user      int                                      null comment '创建人'
+)
+    comment '积分充值/使用记录表' charset = utf8mb4;
+
+create index sys_dept_recharge_record_dept_id_index
+    on sys_dept_recharge_record (dept_id);
+
+
+
+create table sys_dept_invoice
+(
+    id                      int auto_increment comment '主键id'
+        primary key,
+    dept_id                 int                                      null comment '组织机构ID',
+    invoice_amount          decimal(10, 2) default 0.00              not null comment '开票金额(元)',
+    relation_package_score  int            default 0                 not null comment '关联积分值',
+    relation_package_number int            default 0                 not null comment '关联积分包个数',
+    approval_status         varchar(10)    default 'PENDING'         not null comment '审核状态',
+    approval_time           datetime                                 null comment '审核时间',
+    invoice_type            char(10)                                 not null comment '发票类型',
+    address                 varchar(64)                              null comment '邮寄地址',
+    addressee_name          varchar(32)                              null comment '收件人姓名',
+    addressee_phone         varchar(20)                              null comment '收件人手机号',
+    del_flag                varchar(10)    default '0'               not null comment '是否删除',
+    create_time             datetime       default CURRENT_TIMESTAMP null comment '创建时间',
+    create_user             int                                      null comment '创建人',
+    update_time             datetime                                 null comment '更新时间',
+    update_user             int                                      null comment '更新人'
+)
+    comment '企业开票表' charset = utf8mb4;
+
+create index sys_dept_invoice_dept_id_index
+    on sys_dept_invoice (dept_id);
+
+
+create table sys_dept_invoice_relation
+(
+    id             int auto_increment comment '主键id'
+        primary key,
+    invoice_id     int                                   null comment '企业开票表ID',
+    dept_id        int                                   not null comment '发包企业id',
+    package_id     int                                   not null comment '积分包id',
+    invoice_status varchar(10) default 'PENDING'         not null comment '开票状态',
+    invoice_time   datetime                              null comment '开票时间',
+    del_flag       varchar(10) default '0'               not null comment '是否删除',
+    create_time    datetime    default CURRENT_TIMESTAMP null comment '创建/申请时间',
+    create_user    int                                   null comment '创建人',
+    update_time    datetime                              null comment '更新时间',
+    update_user    int                                   null comment '更新人',
+    constraint sys_dept_invoice_relation_invoice_id_package_id_uindex
+        unique (invoice_id, package_id)
+)
+    comment '企业开票关联表' charset = utf8mb4;
+

+ 5 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/CacheConstants.java

@@ -168,4 +168,9 @@ public interface CacheConstants {
 	 */
 	String TASK_APPROVAL_KEY = "TASK:APPROVAL:KEY:";
 
+	/**
+	 * 开票信息缓存key
+	 */
+	String INVOICE_DEPT_KEY = "INVOICE:DEPT:KEY:";
+
 }

+ 2 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/HnqzAdminApplication.java

@@ -22,6 +22,7 @@ package com.qunzhixinxi.hnqz.admin;
 import com.qunzhixinxi.hnqz.common.feign.annotation.EnableHnqzFeignClients;
 import com.qunzhixinxi.hnqz.common.security.annotation.EnableHnqzResourceServer;
 import com.qunzhixinxi.hnqz.common.swagger.annotation.EnableHnqzSwagger2;
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.cloud.client.SpringCloudApplication;
 import org.springframework.retry.annotation.EnableRetry;
@@ -38,6 +39,7 @@ import org.springframework.retry.annotation.EnableRetry;
 @EnableHnqzFeignClients
 @EnableHnqzResourceServer
 @EnableRetry
+@MapperScan(value = {"com.qunzhixinxi.hnqz.admin.mapper", "com.qunzhixinxi.hnqz.admin.recharge.mapper"})
 public class HnqzAdminApplication {
 
 	public static void main(String[] args) {

+ 0 - 1
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmContractController.java

@@ -32,7 +32,6 @@ import java.time.LocalDateTime;
 @AllArgsConstructor
 @RequestMapping("/wmcontract" )
 @Api(value = "wmcontract", tags = "档案-合同管理")
-@MapperScan("com.qunzhixinxi.hnqz.admin.mapper")
 public class WmContractController {
 	private final WmContractService wmContractService;
 

+ 30 - 6
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/enums/DeptLevelEnum.java

@@ -1,23 +1,47 @@
 package com.qunzhixinxi.hnqz.admin.enums;
 
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
 /**
  * 部门级别
  *
  * @author lixuesong
  * @date 2021年12月03日 14:13
  */
+@Getter
+@AllArgsConstructor
 public enum DeptLevelEnum {
 
 	// 1-要易业务管理平台,2-药企,3-一级CSO,4-二级CSO,5-CRO
-	ADMIN(1), ENT(2), CSO_L1(3), CSO_L2(4), CRO(5);
+	ADMIN(1, "要易业务管理平台"),
+	ENT(2, "药企"),
+	CSO_L1(3, "一级CSO"),
+	CSO_L2(4, "二级CSO"),
+	CRO(5, "CRO");
 
+	/**
+	 * level值
+	 */
 	private Integer val;
 
-	DeptLevelEnum(Integer val) {
-		this.val = val;
-	}
+	/**
+	 * 名称
+	 */
+	private String name;
 
-	public Integer getVal() {
-		return val;
+	/**
+	 * 根据val获取枚举
+	 *
+	 * @param val level值
+	 * @return 枚举对象
+	 */
+	public static DeptLevelEnum getEnumByVal(Integer val) {
+		for (DeptLevelEnum deptLevelEnum : DeptLevelEnum.values()) {
+			if (deptLevelEnum.getVal().equals(val)) {
+				return deptLevelEnum;
+			}
+		}
+		return null;
 	}
 }

+ 23 - 11
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/enums/ScorePackageStatusEnum.java

@@ -1,49 +1,61 @@
 package com.qunzhixinxi.hnqz.admin.enums;
 
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
 /**
  * WmScorePackage实体类的scorePackageStatus积分包状态枚举类
  *
  * @author lixuesong
  * @date 2021年05月27日 15:42
  */
+@Getter
+@AllArgsConstructor
 public enum ScorePackageStatusEnum {
 
 	/**
 	 * 已下发待申领
 	 */
-	UNCLAIMED("1"),
+	UNCLAIMED("1", "已下发待申领"),
 	/**
 	 * 已申领待审批
 	 */
-	PENDING_APPROVAL("2"),
+	PENDING_APPROVAL("2", "已申领待审批"),
 	/**
 	 * 进行中
 	 */
-	IN_PROGRESS("3"),
+	IN_PROGRESS("3", "进行中"),
 	/**
 	 * 已完成待结算
 	 */
-	TO_BE_SETTLED("4"),
+	TO_BE_SETTLED("4", "已完成待结算"),
 	/**
 	 * 已提交结算申请
 	 */
-	SETTLEMENT_SUBMITTED("5"),
+	SETTLEMENT_SUBMITTED("5", "已提交结算申请"),
 	/**
 	 * 已终止
 	 */
-	TERMINATED("6"),
+	TERMINATED("6", "已终止"),
 	/**
 	 * 已完成待提交审批
 	 */
-	TO_BE_APPROVAL("7");
+	TO_BE_APPROVAL("7", "已完成待上级审批");
 
-	private String val;
+	private final String val;
 
-	ScorePackageStatusEnum(String val) {
-		this.val = val;
-	}
+	private final String desc;
 
 	public String val() {
 		return this.val;
 	}
+
+	public static ScorePackageStatusEnum getByVal(String val) {
+		for (ScorePackageStatusEnum statusEnum : ScorePackageStatusEnum.values()) {
+			if (statusEnum.val.equals(val)) {
+				return statusEnum;
+			}
+		}
+		return null;
+	}
 }

+ 172 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/controller/SysDeptInvoiceController.java

@@ -0,0 +1,172 @@
+package com.qunzhixinxi.hnqz.admin.recharge.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysDept;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptInvoiceRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoice;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptInvoiceService;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceVO;
+import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
+import com.qunzhixinxi.hnqz.common.core.util.R;
+import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 企业开票前端控制器
+ *
+ * @author snows
+ * @date 2023/6/16 14:49
+ */
+@Slf4j
+@RestController
+@AllArgsConstructor
+@RequestMapping("/dept/invoice")
+public class SysDeptInvoiceController {
+
+    private final SysDeptInvoiceService deptInvoiceService;
+    private final SysDeptService deptService;
+    private final RedisTemplate redisTemplate;
+
+    /**
+     * 开票申请
+     *
+     * @param toInvoice 开票参数
+     * @return 响应结果
+     */
+    @SysLog("园区-开票申请")
+    @PostMapping
+    public R<?> toInvoice(@Validated @RequestBody SysDeptInvoiceRequest.ToInvoice toInvoice) {
+        log.info("园区-开票申请请求参数:{}", toInvoice);
+        return R.ok(deptInvoiceService.toInvoice(toInvoice));
+    }
+
+    /**
+     * 开票审核
+     *
+     * @param toApprove 开票审核
+     * @return 响应结果
+     */
+    @SysLog("平台财务-开票审核")
+    @PostMapping("/to-approve")
+    public R<?> toApprove(@Validated @RequestBody SysDeptInvoiceRequest.ToApprove toApprove) {
+        log.info("平台财务-开票审核请求参数:{}", toApprove);
+        return R.ok(deptInvoiceService.toApprove(toApprove));
+    }
+
+//    /**
+//     * 园区-开票管理列表
+//     *
+//     * @param page               分页参数
+//     * @param toScorePackagePage 请求参数
+//     * @return 响应结果
+//     */
+//    @GetMapping("/page-invoice-for-park")
+//    public R<IPage<SysDeptInvoiceRelationVO>> pageInvoiceForPark(Page<SysDeptInvoiceRelationVO> page, SysDeptInvoiceRequest.ToScorePackagePage toScorePackagePage) {
+//
+//        return R.ok(deptInvoiceService.pageInvoiceForPark(page, toScorePackagePage));
+//    }
+
+    /**
+     * 平台财务管理-开票列表
+     *
+     * @param page          分页参数
+     * @param toInvoicePage 请求参数
+     * @return 响应结果
+     */
+    @GetMapping("/page-invoice-for-admin")
+    public R<IPage<SysDeptInvoiceVO>> pageInvoiceForAdmin(Page<SysDeptInvoiceVO> page, SysDeptInvoiceRequest.ToInvoicePage toInvoicePage) {
+
+        return R.ok(deptInvoiceService.pageInvoiceForAdmin(page, toInvoicePage));
+    }
+
+//    /**
+//     * 园区-开票列表
+//     *
+//     * @param page          分页参数
+//     * @param toInvoicePage 请求参数
+//     * @return 响应结果
+//     */
+//    @GetMapping("/page-invoice-record")
+//    public R<IPage<SysDeptInvoiceVO>> pageInvoiceRecordForPark(Page<SysDeptInvoiceVO> page, SysDeptInvoiceRequest.ToInvoicePage toInvoicePage) {
+//
+//        return R.ok(deptInvoiceService.pageInvoiceRecordForPark(page, toInvoicePage));
+//    }
+
+    /**
+     * 平台财务-关联积分包列表
+     *
+     * @param page   分页参数
+     * @param invoiceId 企业开票表ID
+     * @return 响应结果
+     */
+    @GetMapping("/page-invoice")
+    public R<IPage<SysDeptInvoiceRelationVO>> pageInvoice(Page<SysDeptInvoiceRelationVO> page, @RequestParam("invoiceId") Integer invoiceId) {
+
+        return R.ok(deptInvoiceService.pageInvoice(page, invoiceId));
+    }
+
+    /**
+     * 开票详情(园区)
+     *
+     * @param invoiceId 开票id
+     * @return 结果
+     */
+    @GetMapping("/detail/{invoiceId}")
+    public R<SysDeptInvoiceVO> invoiceDetail(@PathVariable("invoiceId") Integer invoiceId) {
+        SysDeptInvoice deptInvoice = deptInvoiceService.getById(invoiceId);
+        if (deptInvoice != null) {
+            SysDeptInvoiceVO deptInvoiceVO = BeanUtil.copyProperties(deptInvoice, SysDeptInvoiceVO.class);
+            SysDept dept = deptService.getById(deptInvoice.getDeptId());
+            deptInvoiceVO.setDeptName(dept.getName());
+            deptInvoiceVO.setApprovalStatusStr(deptInvoice.getApprovalStatus().getDescription());
+            deptInvoiceVO.setInvoiceTypeStr(deptInvoice.getInvoiceType().getDescription());
+            return R.ok(deptInvoiceVO);
+        }
+        return R.ok();
+    }
+
+    /**
+     * 获取缓存开票信息
+     *
+     * @return 缓存开票信息
+     */
+    @GetMapping("/cache-invoice-info")
+    public R<?> getCacheInvoiceInfo() {
+        String cacheKey = CacheConstants.INVOICE_DEPT_KEY + SecurityUtils.getUser().getDeptId();
+        String cacheVal = (String) redisTemplate.opsForValue().get(cacheKey);
+        Map<String, String> result = new HashMap<>();
+        if (StrUtil.isBlank(cacheVal)) {
+            result.put("addresseeName", "");
+            result.put("address", "");
+            result.put("addresseePhone", "");
+            result.put("invoiceType", "");
+            return R.ok(result);
+        }
+        SysDeptInvoice deptInvoice = JSONUtil.toBean(cacheVal, SysDeptInvoice.class);
+        result.put("addresseeName", deptInvoice.getAddresseeName());
+        result.put("address", deptInvoice.getAddress());
+        result.put("addresseePhone", deptInvoice.getAddresseePhone());
+        result.put("invoiceType", deptInvoice.getInvoiceType().getType());
+        return R.ok(result);
+    }
+}

+ 191 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/controller/SysDeptRechargeController.java

@@ -0,0 +1,191 @@
+package com.qunzhixinxi.hnqz.admin.recharge.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptRechargeRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoice;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRecharge;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRechargeRecord;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceApprovalStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptInvoiceRelationMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptInvoiceService;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptRechargeRecordService;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptRechargeService;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeRecordForDeptVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeRecordVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeVO;
+import com.qunzhixinxi.hnqz.admin.service.SysDeptRelationService;
+import com.qunzhixinxi.hnqz.common.core.util.R;
+import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+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.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 企业充值管理前端控制器
+ *
+ * @author snows
+ * @date 2023/6/12 11:17
+ */
+@Slf4j
+@RestController
+@AllArgsConstructor
+@RequestMapping("/dept/recharge")
+public class SysDeptRechargeController {
+
+    private final SysDeptRechargeService deptRechargeService;
+
+    private final SysDeptRechargeRecordService deptRechargeRecordService;
+
+    private final SysDeptInvoiceService deptInvoiceService;
+
+    /**
+     * 配置(权限管理)
+     *
+     * @param toConfig 配置参数
+     * @return 结果
+     */
+    @SysLog("配置(平台财务-权限管理)")
+    @PostMapping("/to-config")
+    public R<?> toConfig(@RequestBody @Validated SysDeptRechargeRequest.ToConfig toConfig) {
+        log.info("配置(平台财务-权限管理)入参:{}", toConfig);
+        return R.ok(deptRechargeService.toConfig(toConfig));
+    }
+
+    /**
+     * 充值(平台财务)
+     *
+     * @param toRecharge 充值参数
+     * @return 充值结果
+     */
+    @SysLog("充值(平台财务)")
+    @PostMapping
+    public R<?> toRecharge(@Validated @RequestBody SysDeptRechargeRequest.ToRecharge toRecharge) {
+        log.info("充值(平台财务)入参:{}", toRecharge);
+        return R.ok(deptRechargeService.recharge(toRecharge));
+    }
+
+    /**
+     * 分页查询(平台财务)
+     *
+     * @param page 分页参数
+     * @param toPage 条件参数
+     * @return 分页结果
+     */
+    @GetMapping("/page")
+    public R<IPage<SysDeptRechargeVO>> pageRechargeForAdmin(Page<SysDeptRechargeVO> page, SysDeptRechargeRequest.ToPage toPage) {
+        return R.ok(deptRechargeService.pageRechargeForAdmin(page, toPage));
+    }
+
+//    /**
+//     * 分页查询(园区)
+//     *
+//     * @param page 分页参数
+//     * @param toPage 条件参数
+//     * @return 分页结果
+//     */
+//    @GetMapping("/page-for-park")
+//    public R<IPage<SysDeptRechargeForParkVO>> pageRechargeForPark(Page<SysDeptRechargeForParkVO> page, SysDeptRechargeRequest.ToPage toPage) {
+//        return R.ok(deptRechargeService.pageRechargeForPark(page, toPage));
+//    }
+
+    /**
+     * 积分充值/分配/发包记录(平台财务/园区)
+     *
+     * @param page 分页参数
+     * @return 分页结果
+     */
+    @GetMapping("/page-recharge-record")
+    public R<IPage<SysDeptRechargeRecordVO>> pageRechargeRecord(Page<SysDeptRechargeRecordVO> page, @Validated SysDeptRechargeRequest.ToAdminRecordPage toAdminRecordPage) {
+        return R.ok(deptRechargeRecordService.pageRechargeRecord(page, toAdminRecordPage.getDeptId()));
+    }
+
+    /**
+     * 积分分配/发包记录(企业)
+     *
+     * @param page 分页参数
+     * @return 分页结果
+     */
+    @GetMapping("/page-record-for-dept")
+    public R<IPage<SysDeptRechargeRecordForDeptVO>> pageRecordForDept(Page<SysDeptRechargeRecordForDeptVO> page, SysDeptRechargeRequest.ToRecordPage toRecordPage) {
+        return R.ok(deptRechargeRecordService.pageRecordForDept(page, toRecordPage.getType(), toRecordPage.getCreateTime()));
+    }
+
+    /**
+     * 企业-数据总览
+     *
+     * @return 结果
+     */
+    @GetMapping("/dept-overview")
+    public R<?> deptScoreOverview() {
+        Integer deptId = SecurityUtils.getUser().getDeptId();
+        SysDeptRecharge deptRecharge = deptRechargeService.getOne(Wrappers.<SysDeptRecharge>lambdaQuery()
+                .eq(SysDeptRecharge::getDeptId, deptId)
+                .eq(SysDeptRecharge::getDelFlag, DelEnum.NOT_DEL.val()));
+
+        Map<String, Integer> result = new HashMap<>(4);
+        if (deptRecharge == null) {
+            result.put("score", 0);
+            result.put("usedScore", 0);
+            result.put("toInvoiceScore", 0);
+            result.put("invoicedScore", 0);
+        } else {
+            // 积分余额
+            result.put("score", deptRecharge.getScore());
+            // 本月消耗积分
+            List<SysDeptRechargeRecord> usedRecords = deptRechargeRecordService.list(Wrappers.<SysDeptRechargeRecord>lambdaQuery()
+                    .eq(SysDeptRechargeRecord::getDeptId, deptId)
+                    .eq(SysDeptRechargeRecord::getDelFlag, DelEnum.NOT_DEL.val()));
+            int usedScore = usedRecords.stream().mapToInt(SysDeptRechargeRecord::getChangeScore).sum();
+            result.put("usedScore", Math.abs(usedScore));
+
+            // 可开票记录
+            List<SysDeptInvoiceRelationVO> relationVOS = deptInvoiceService.listToInvoiceScore(deptId);
+            if (CollUtil.isNotEmpty(relationVOS)) {
+                // 可开票积分
+                result.put("toInvoiceScore", relationVOS.stream().mapToInt(SysDeptInvoiceRelationVO::getScore).sum());
+            } else {
+                // 可开票积分
+                result.put("toInvoiceScore", 0);
+            }
+
+            // 当月时间范围
+            LocalDate nowDate = LocalDate.now();
+            LocalDateTime startTime = nowDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay();
+            LocalDateTime endTime = nowDate.plusMonths(1L).with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay();
+            List<SysDeptInvoice> monthInvoices = deptInvoiceService.list(Wrappers.<SysDeptInvoice>lambdaQuery()
+                    .eq(SysDeptInvoice::getDeptId, deptId)
+                    .eq(SysDeptInvoice::getDelFlag, DelEnum.NOT_DEL.val())
+                    .eq(SysDeptInvoice::getApprovalStatus, InvoiceApprovalStatus.PASSED)
+                    .between(SysDeptInvoice::getApprovalTime, startTime, endTime));
+            if (CollUtil.isNotEmpty(monthInvoices)) {
+                // 本月已开票积分
+                result.put("invoicedScore", monthInvoices.stream().mapToInt(SysDeptInvoice::getRelationPackageScore).sum());
+            } else {
+                // 本月已开票积分
+                result.put("invoicedScore", 0);
+            }
+        }
+
+        return R.ok(result);
+    }
+
+
+}

+ 128 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/dto/SysDeptInvoiceRequest.java

@@ -0,0 +1,128 @@
+package com.qunzhixinxi.hnqz.admin.recharge.dto;
+
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceApprovalStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceType;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 开票相关请求
+ *
+ * @author snows
+ * @date 2023/6/16 15:13
+ */
+public class SysDeptInvoiceRequest {
+
+    /**
+     * 开票请求参数
+     */
+    @Data
+    public static class ToInvoice implements Serializable {
+        private static final long serialVersionUID = -6254095346012051281L;
+
+        /**
+         * 积分包id列表
+         */
+        @NotEmpty(message = "积分包id列表必填")
+        private String[] packageIds;
+
+        /**
+         * 开票主体
+         */
+//        @NotNull(message = "开票主体必填")
+//        private Integer deptId;
+
+        /**
+         * 发票类型
+         */
+        @NotNull(message = "发票类型必填")
+        private InvoiceType invoiceType;
+
+        /**
+         * 邮寄地址
+         */
+        private String address;
+
+        /**
+         * 收件人姓名
+         */
+        private String addresseeName;
+
+        /**
+         * 收件人手机号
+         */
+        private String addresseePhone;
+    }
+
+    /**
+     * 开票审核
+     */
+    @Data
+    public static class ToApprove implements Serializable {
+        private static final long serialVersionUID = 6518694561688554330L;
+
+        /**
+         * 开票id
+         */
+        @NotNull(message = "开票id必填")
+        private Integer invoiceId;
+
+        /**
+         * 审核状态
+         */
+        @NotNull(message = "审核状态必填")
+        private InvoiceApprovalStatus approvalStatus;
+
+    }
+
+    /**
+     * 开票管理请求参数
+     */
+    @Data
+    public static class ToScorePackagePage implements Serializable {
+        private static final long serialVersionUID = -7835160794495661536L;
+
+        /**
+         * 发布时间
+         */
+        private LocalDateTime[] createTime;
+
+        /**
+         * 发包企业
+         */
+        private String deptName;
+
+        /**
+         * 开票状态
+         */
+        private InvoiceStatus invoiceStatus;
+    }
+
+    /**
+     * 开票管理请求参数(平台管理员)
+     */
+    @Data
+    public static class ToInvoicePage implements Serializable {
+        private static final long serialVersionUID = -7645242691493270586L;
+
+        /**
+         * 申请时间
+         */
+        private LocalDateTime[] createTime;
+
+        /**
+         * 开票主体
+         */
+        private String deptName;
+
+        /**
+         * 开票状态
+         */
+        private InvoiceApprovalStatus approvalStatus;
+    }
+}

+ 151 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/dto/SysDeptRechargeRequest.java

@@ -0,0 +1,151 @@
+package com.qunzhixinxi.hnqz.admin.recharge.dto;
+
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 积分充值请求
+ *
+ * @author snows
+ * @date 2023/6/12 11:23
+ */
+public class SysDeptRechargeRequest implements Serializable {
+    private static final long serialVersionUID = -7104300633204592299L;
+
+    /**
+     * 积分充值分页参数
+     */
+    @Data
+    public static class ToPage implements Serializable {
+        private static final long serialVersionUID = 9102286943907340580L;
+
+        /**
+         * 企业名称
+         */
+        private String deptName;
+
+        /**
+         * 企业类型(级别)
+         */
+        private Integer deptLevel;
+    }
+
+    /**
+     * 积分记录分页参数
+     */
+    @Data
+    public static class ToRecordPage implements Serializable {
+        private static final long serialVersionUID = -7774101561321194648L;
+
+        /**
+         * 企业名称
+         */
+        private String deptName;
+
+        /**
+         * 操作类型
+         */
+        private RechargeRecordType type;
+
+        /**
+         * 操作时间范围
+         */
+        private LocalDateTime[] createTime;
+    }
+
+    /**
+     * 积分充值记录分页参数(平台财务、园区)
+     */
+    @Data
+    public static class ToAdminRecordPage implements Serializable {
+        private static final long serialVersionUID = -7774101561321194648L;
+
+        /**
+         * 企业id
+         */
+        @NotNull(message = "企业id必填")
+        private Integer deptId;
+    }
+
+    /**
+     * 充值参数
+     */
+    @Data
+    public static class ToRecharge implements Serializable {
+        private static final long serialVersionUID = 1444649528911261490L;
+
+        /**
+         * 企业id
+         */
+        @NotNull(message = "企业id必填")
+        private Integer deptId;
+
+        /**
+         * 充值金额
+         */
+        @NotNull(message = "充值金额必填")
+        private BigDecimal rechargeAmount;
+
+        /**
+         * 充值积分
+         */
+        @NotNull(message = "充值积分必填")
+        private Integer rechargeScore;
+    }
+
+    /**
+     * 配置(权限管理)参数
+     */
+    @Data
+    public static class ToConfig implements Serializable {
+        private static final long serialVersionUID = 3654419027796689016L;
+
+        /**
+         * 企业id
+         */
+        @NotNull(message = "企业id必填")
+        private Integer deptId;
+
+        /**
+         * 服务费率
+         */
+        @NotNull(message = "服务费率必填")
+        private BigDecimal serviceCharge;
+
+        /**
+         * 权限
+         */
+        private String[] permissions;
+
+        /**
+         * 可透支积分
+         */
+        private Integer overdrawScore;
+    }
+
+    /**
+     * 积分分配参数
+     */
+    @Data
+    public static class ToDistribute implements Serializable {
+        private static final long serialVersionUID = -5449648571357801707L;
+
+        /**
+         * 企业id
+         */
+        @NotNull(message = "企业id必填")
+        private Integer deptId;
+
+        /**
+         * 分配积分
+         */
+        @NotNull(message = "分配积分必填")
+        private Integer distributeScore;
+
+    }
+}

+ 103 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptInvoice.java

@@ -0,0 +1,103 @@
+package com.qunzhixinxi.hnqz.admin.recharge.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceApprovalStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceType;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 企业开票表
+ * @TableName sys_dept_invoice
+ */
+@TableName(value ="sys_dept_invoice")
+@Data
+public class SysDeptInvoice implements Serializable {
+    private static final long serialVersionUID = -4830423850806042441L;
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 开票金额(元)
+     */
+    private BigDecimal invoiceAmount;
+
+    /**
+     * 关联积分值
+     */
+    private Integer relationPackageScore;
+
+    /**
+     * 关联积分包个数
+     */
+    private Integer relationPackageNumber;
+
+    /**
+     * 审核状态
+     */
+    private InvoiceApprovalStatus approvalStatus;
+
+    /**
+     * 审核时间
+     */
+    private LocalDateTime approvalTime;
+
+    /**
+     * 发票类型
+     */
+    private InvoiceType invoiceType;
+
+    /**
+     * 邮寄地址
+     */
+    private String address;
+
+    /**
+     * 收件人姓名
+     */
+    private String addresseeName;
+
+    /**
+     * 收件人手机号
+     */
+    private String addresseePhone;
+
+    /**
+     * 是否删除
+     */
+    private String delFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private Integer updateUser;
+}

+ 77 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptInvoiceRelation.java

@@ -0,0 +1,77 @@
+package com.qunzhixinxi.hnqz.admin.recharge.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceStatus;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 企业开票关联表
+ * @TableName sys_dept_invoice_relation
+ */
+@TableName(value ="sys_dept_invoice_relation")
+@Data
+public class SysDeptInvoiceRelation implements Serializable {
+    private static final long serialVersionUID = 6309513073341858328L;
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 发包企业id
+     */
+    private Integer deptId;
+
+    /**
+     * 积分包id
+     */
+    private String packageId;
+
+    /**
+     * 企业开票表ID
+     */
+    private Integer invoiceId;
+
+    /**
+     * 开票状态
+     */
+    private InvoiceStatus invoiceStatus;
+
+    /**
+     * 开票时间
+     */
+    private LocalDateTime invoiceTime;
+
+    /**
+     * 是否删除
+     */
+    private String delFlag;
+
+    /**
+     * 创建/申请时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private Integer updateUser;
+
+}

+ 91 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptRecharge.java

@@ -0,0 +1,91 @@
+package com.qunzhixinxi.hnqz.admin.recharge.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 积分充值表
+ * @TableName sys_dept_recharge
+ */
+@Data
+@TableName(value ="sys_dept_recharge")
+public class SysDeptRecharge implements Serializable {
+    private static final long serialVersionUID = 4837376098052280830L;
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 积分余额
+     */
+    private Integer score;
+
+    /**
+     * 余额(元)
+     */
+    private BigDecimal balance;
+
+    /**
+     * 权限
+     */
+    private String[] permissions;
+
+    /**
+     * 服务费率
+     */
+    private BigDecimal serviceCharge;
+
+    /**
+     * 可透支金额
+     */
+    private BigDecimal overdrawAmount;
+
+    /**
+     * 可透支积分
+     */
+    private Integer overdrawScore;
+
+    /**
+     * 删除状态
+     */
+    private String delFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private Integer updateUser;
+
+    /**
+     * 锁
+     */
+    private Integer version;
+}

+ 94 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/entity/SysDeptRechargeRecord.java

@@ -0,0 +1,94 @@
+package com.qunzhixinxi.hnqz.admin.recharge.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordPackageType;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 积分充值/使用记录表
+ * @TableName sys_dept_recharge_record
+ */
+@TableName(value ="sys_dept_recharge_record")
+@Data
+public class SysDeptRechargeRecord implements Serializable {
+    private static final long serialVersionUID = -7732924467238140614L;
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 积分充值表ID
+     */
+    private Integer rechargeId;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 关联组织机构ID(关联操作对象)
+     */
+    private Integer relationDeptId;
+
+    /**
+     * 充值积分
+     */
+    private Integer changeScore;
+
+    /**
+     * 充值金额(元)
+     */
+    private BigDecimal changeAmount;
+
+    /**
+     * 操作类型
+     */
+    private RechargeRecordType type;
+
+    /**
+     * 充值后积分余额
+     */
+    private Integer currentScore;
+
+    /**
+     * 充值后积分余额(元)
+     */
+    private BigDecimal currentBalance;
+
+    /**
+     * 积分包id
+     */
+    private String packageId;
+
+    /**
+     * 积分包类型
+     */
+    private RechargeRecordPackageType packageType;
+
+    /**
+     * 是否删除
+     */
+    private String delFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+}

+ 25 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/InvoiceApprovalStatus.java

@@ -0,0 +1,25 @@
+package com.qunzhixinxi.hnqz.admin.recharge.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 企业开票-审核状态
+ *
+ * @author snows
+ * @date 2023/6/16 11:56
+ */
+@Getter
+@AllArgsConstructor
+public enum InvoiceApprovalStatus {
+
+    PENDING("PENDING", "待审核"),
+    PASSED("PASSED", "已开票"),
+    REJECTED("REJECTED", "驳回");
+
+    @EnumValue
+    private final String status;
+
+    private final String description;
+}

+ 43 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/InvoiceStatus.java

@@ -0,0 +1,43 @@
+package com.qunzhixinxi.hnqz.admin.recharge.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 企业开票-开票状态
+ *
+ * @author snows
+ * @date 2023/6/16 11:56
+ */
+@Getter
+@AllArgsConstructor
+public enum InvoiceStatus {
+
+    NOT_APPLY("NOT_APPLY", "未申请"),
+    PENDING("PENDING", "待审核"),
+    PASSED("PASSED", "已开票");
+
+    @EnumValue
+    private final String status;
+
+    private final String description;
+
+    /**
+     * 根据审核状态获取发票状态
+     *
+     * @param approvalStatus 审核状态
+     * @return 发票状态
+     */
+    public static InvoiceStatus getByApproveStatus(InvoiceApprovalStatus approvalStatus) {
+        switch (approvalStatus) {
+            case PASSED:
+                return InvoiceStatus.PASSED;
+            case REJECTED:
+                return InvoiceStatus.NOT_APPLY;
+            case PENDING:
+                return InvoiceStatus.PENDING;
+        }
+        return null;
+    }
+}

+ 24 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/InvoiceType.java

@@ -0,0 +1,24 @@
+package com.qunzhixinxi.hnqz.admin.recharge.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 开票-发票类型
+ *
+ * @author snows
+ * @date 2023/6/19 13:51
+ */
+@Getter
+@AllArgsConstructor
+public enum InvoiceType {
+
+    GENERAL("GENERAL", "普票"),
+    SPECIAL("SPECIAL", "专票");
+
+    @EnumValue
+    private final String type;
+
+    private final String description;
+}

+ 24 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/RechargeRecordPackageType.java

@@ -0,0 +1,24 @@
+package com.qunzhixinxi.hnqz.admin.recharge.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 积分记录-积分包类型
+ *
+ * @author snows
+ * @date 2023/6/14 16:31
+ */
+@Getter
+@AllArgsConstructor
+public enum RechargeRecordPackageType {
+
+    TO_PERSON("TO_PERSON", "给个人的包"),
+    TO_ENTERPRISE("TO_ENTERPRISE", "给企业的包");
+
+    @EnumValue
+    private final String type;
+
+    private final String description;
+}

+ 29 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/enums/RechargeRecordType.java

@@ -0,0 +1,29 @@
+package com.qunzhixinxi.hnqz.admin.recharge.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 积分充值记录操作类型
+ *
+ * @author snows
+ * @date 2023/6/12 14:42
+ */
+@Getter
+@AllArgsConstructor
+public enum RechargeRecordType {
+
+    RECHARGE("RECHARGE", "充值"),
+//    DISTRIBUTE("DISTRIBUTE", "分配积分"),
+    SEND_PACKAGE_DEPT("SEND_PACKAGE_DEPT", "发包-企业"),
+    SEND_PACKAGE_PERSONAL("SEND_PACKAGE_PERSONAL", "发包-个人"),
+    RECOVERY("RECOVERY", "修改积分包");
+
+    @EnumValue
+    private final String type;
+
+    private final String description;
+
+
+}

+ 20 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptInvoiceMapper.java

@@ -0,0 +1,20 @@
+package com.qunzhixinxi.hnqz.admin.recharge.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoice;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_invoice(企业开票表)】的数据库操作Mapper
+* @createDate 2023-06-16 14:08:32
+* @Entity com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoice
+*/
+@Mapper
+public interface SysDeptInvoiceMapper extends BaseMapper<SysDeptInvoice> {
+
+}
+
+
+
+

+ 58 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptInvoiceRelationMapper.java

@@ -0,0 +1,58 @@
+package com.qunzhixinxi.hnqz.admin.recharge.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptInvoiceRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoiceRelation;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_invoice_relation(企业开票关联表)】的数据库操作Mapper
+* @createDate 2023-06-16 14:28:24
+* @Entity com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoiceRelation
+*/
+@Mapper
+public interface SysDeptInvoiceRelationMapper extends BaseMapper<SysDeptInvoiceRelation> {
+
+    /**
+     * 开票和积分包关联查询
+     *
+     * @param page 分页参数
+     * @param toScorePackagePage 查询条件参数
+     * @param deptIdList 企业id列表
+     * @return 分页结果
+     */
+    IPage<SysDeptInvoiceRelationVO> pageInvoiceScorePacakgeRelation(Page<SysDeptInvoiceRelation> page,
+                                                                    @Param("query") SysDeptInvoiceRequest.ToScorePackagePage toScorePackagePage,
+                                                                    @Param("deptIdList") Set<Integer> deptIdList);
+
+    /**
+     * 开票和积分包关联查询
+     *
+     * @param toScorePackagePage 查询条件参数
+     * @param deptIdList 企业id列表
+     * @return 分页结果
+     */
+    List<SysDeptInvoiceRelationVO> listInvoiceScorePacakgeRelation(@Param("query") SysDeptInvoiceRequest.ToScorePackagePage toScorePackagePage,
+                                                                   @Param("deptIdList") Set<Integer> deptIdList);
+
+    /**
+     * 开票和积分包关联查询2
+     *
+     * @param page      分页参数
+     * @param invoiceId 企业开票表ID
+     * @return 分页结果
+     */
+    IPage<SysDeptInvoiceRelationVO> pageInvoiceScorePacakgeRelation2(Page<SysDeptInvoiceRelation> page, @Param("invoiceId") Integer invoiceId);
+}
+
+
+
+

+ 20 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptRechargeMapper.java

@@ -0,0 +1,20 @@
+package com.qunzhixinxi.hnqz.admin.recharge.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRecharge;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_recharge(积分充值表)】的数据库操作Mapper
+* @createDate 2023-06-12 10:47:24
+* @Entity com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRecharge
+*/
+@Mapper
+public interface SysDeptRechargeMapper extends BaseMapper<SysDeptRecharge> {
+
+}
+
+
+
+

+ 20 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/mapper/SysDeptRechargeRecordMapper.java

@@ -0,0 +1,20 @@
+package com.qunzhixinxi.hnqz.admin.recharge.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRechargeRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_recharge_record(积分充值/使用记录表)】的数据库操作Mapper
+* @createDate 2023-06-12 14:40:23
+* @Entity com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRechargeRecord
+*/
+@Mapper
+public interface SysDeptRechargeRecordMapper extends BaseMapper<SysDeptRechargeRecord> {
+
+}
+
+
+
+

+ 13 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptInvoiceRelationService.java

@@ -0,0 +1,13 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoiceRelation;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_invoice_relation(企业开票关联表)】的数据库操作Service
+* @createDate 2023-06-16 14:28:24
+*/
+public interface SysDeptInvoiceRelationService extends IService<SysDeptInvoiceRelation> {
+
+}

+ 78 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptInvoiceService.java

@@ -0,0 +1,78 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptInvoiceRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoice;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceVO;
+
+import java.util.List;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_invoice(企业开票表)】的数据库操作Service
+* @createDate 2023-06-16 14:08:32
+*/
+public interface SysDeptInvoiceService extends IService<SysDeptInvoice> {
+
+//    /**
+//     * 园区-开票管理列表
+//     *
+//     * @param toScorePackagePage 分页参数
+//     * @return 分页结果
+//     */
+//    IPage<SysDeptInvoiceRelationVO> pageInvoiceForPark(Page<SysDeptInvoiceRelationVO> page, SysDeptInvoiceRequest.ToScorePackagePage toScorePackagePage);
+
+    /**
+     * 平台财务管理-开票列表
+     *
+     * @param page 分页参数
+     * @param toInvoicePage 请求参数
+     * @return 响应结果
+     */
+    IPage<SysDeptInvoiceVO> pageInvoiceForAdmin(Page<SysDeptInvoiceVO> page, SysDeptInvoiceRequest.ToInvoicePage toInvoicePage);
+
+//    /**
+//     * 园区-开票列表
+//     *
+//     * @param page 分页参数
+//     * @param toInvoicePage 请求参数
+//     * @return 响应结果
+//     */
+//    IPage<SysDeptInvoiceVO> pageInvoiceRecordForPark(Page<SysDeptInvoiceVO> page, SysDeptInvoiceRequest.ToInvoicePage toInvoicePage);
+
+    /**
+     * 平台财务-关联积分包列表
+     *
+     * @param page   分页参数
+     * @param invoiceId 企业开票表ID
+     * @return 响应结果
+     */
+    IPage<SysDeptInvoiceRelationVO> pageInvoice(Page<SysDeptInvoiceRelationVO> page, Integer invoiceId);
+
+    /**
+     * 可开票积分
+     *
+     * @param deptId 企业id
+     * @return 可开票积分记录
+     */
+    List<SysDeptInvoiceRelationVO> listToInvoiceScore(Integer deptId);
+
+    /**
+     * 开发票
+     *
+     * @param toInvoice 开票参数
+     * @return 响应结果
+     */
+    Boolean toInvoice(SysDeptInvoiceRequest.ToInvoice toInvoice);
+
+    /**
+     * 开票审核
+     *
+     * @param toApprove 开票参数
+     * @return 响应结果
+     */
+    Boolean toApprove(SysDeptInvoiceRequest.ToApprove toApprove);
+}

+ 39 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptRechargeRecordService.java

@@ -0,0 +1,39 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRechargeRecord;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeRecordForDeptVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeRecordVO;
+
+import java.time.LocalDateTime;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_recharge_record(积分充值/使用记录表)】的数据库操作Service
+* @createDate 2023-06-12 14:40:23
+*/
+public interface SysDeptRechargeRecordService extends IService<SysDeptRechargeRecord> {
+
+    /**
+     * 充值记录
+     *
+     * @param page       分页参数
+     * @param deptId     企业id
+     * @return 分页结果
+     */
+    IPage<SysDeptRechargeRecordVO> pageRechargeRecord(Page<SysDeptRechargeRecordVO> page, Integer deptId);
+
+    /**
+     * 分配、发包记录(企业)
+     *
+     * @param page       分页参数
+     * @param type       操作类型
+     * @param createTime 创建时间范围
+     * @return 分页结果
+     */
+    IPage<SysDeptRechargeRecordForDeptVO> pageRecordForDept(Page<SysDeptRechargeRecordForDeptVO> page,
+                                                            RechargeRecordType type, LocalDateTime[] createTime);
+}

+ 42 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/SysDeptRechargeService.java

@@ -0,0 +1,42 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptRechargeRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRecharge;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeVO;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_recharge(积分充值表)】的数据库操作Service
+* @createDate 2023-06-12 10:47:24
+*/
+public interface SysDeptRechargeService extends IService<SysDeptRecharge> {
+
+    /**
+     * 分页查询(平台财务)
+     *
+     * @param page 分页参数
+     * @param toPage 条件参数
+     * @return 分页结果
+     */
+    IPage<SysDeptRechargeVO> pageRechargeForAdmin(Page<SysDeptRechargeVO> page, SysDeptRechargeRequest.ToPage toPage);
+
+    /**
+     * 充值
+     *
+     * @param toRecharge 充值参数
+     * @return 结果
+     */
+    Boolean recharge(SysDeptRechargeRequest.ToRecharge toRecharge);
+
+    /**
+     * 配置(权限管理)
+     *
+     * @param toConfig 配置参数
+     * @return 结果
+     */
+    Boolean toConfig(SysDeptRechargeRequest.ToConfig toConfig);
+
+}

+ 22 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptInvoiceRelationServiceImpl.java

@@ -0,0 +1,22 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoiceRelation;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptInvoiceRelationMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptInvoiceRelationService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_invoice_relation(企业开票关联表)】的数据库操作Service实现
+* @createDate 2023-06-16 14:28:24
+*/
+@Service
+public class SysDeptInvoiceRelationServiceImpl extends ServiceImpl<SysDeptInvoiceRelationMapper, SysDeptInvoiceRelation>
+    implements SysDeptInvoiceRelationService{
+
+}
+
+
+
+

+ 499 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptInvoiceServiceImpl.java

@@ -0,0 +1,499 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysDept;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysDeptRelation;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackage;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackageStatus;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.PackageStatusEnum;
+import com.qunzhixinxi.hnqz.admin.enums.ScorePackageStatusEnum;
+import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageMapper;
+import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageStatusMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptInvoiceRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoice;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoiceRelation;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRecharge;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceApprovalStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptInvoiceMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptInvoiceRelationMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptRechargeMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptInvoiceRelationService;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptInvoiceService;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceVO;
+import com.qunzhixinxi.hnqz.admin.service.SysDeptRelationService;
+import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
+import com.qunzhixinxi.hnqz.admin.service.SysUserService;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_invoice(企业开票表)】的数据库操作Service实现
+* @createDate 2023-06-16 14:08:32
+*/
+@Slf4j
+@Service
+@AllArgsConstructor
+public class SysDeptInvoiceServiceImpl extends ServiceImpl<SysDeptInvoiceMapper, SysDeptInvoice>
+    implements SysDeptInvoiceService {
+
+    private final SysDeptRelationService deptRelationService;
+    private final WmScorePackageMapper scorePackageMapper;
+    private final WmScorePackageStatusMapper scorePackageStatusMapper;
+    private final SysUserService userService;
+    private final SysDeptService deptService;
+    private final SysDeptInvoiceRelationService deptInvoiceRelationService;
+    private final SysDeptInvoiceRelationMapper deptInvoiceRelationMapper;
+    private final SysDeptRechargeMapper deptRechargeMapper;
+    private final RedisTemplate redisTemplate;
+
+//    /**
+//     * 园区-开票管理列表
+//     *
+//     * @param toScorePackagePage 分页参数
+//     * @return 分页结果
+//     */
+//    @Override
+//    public IPage<SysDeptInvoiceRelationVO> pageInvoiceForPark(Page<SysDeptInvoiceRelationVO> page, SysDeptInvoiceRequest.ToScorePackagePage toScorePackagePage) {
+//
+//        Integer deptId = SecurityUtils.getUser().getDeptId();
+//        List<SysJyEntRelation> jyEnts = jyEntRelationService.list(Wrappers.<SysJyEntRelation>lambdaQuery()
+//                .eq(SysJyEntRelation::getJyDept, deptId));
+//        if (CollUtil.isEmpty(jyEnts)) {
+//            return page;
+//        }
+//
+//        // 查询园区关联的企业
+//        Set<Integer> queryDeptIds = new HashSet<>();
+//        Set<Integer> jyEntRelationDeptIds = jyEnts.stream().map(SysJyEntRelation::getEntDept).collect(Collectors.toSet());
+//        List<SysDeptRelation> deptRelations = deptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
+//                .in(SysDeptRelation::getAncestor, jyEntRelationDeptIds)
+//                .notIn(SysDeptRelation::getDescendant, jyEntRelationDeptIds));
+//        if (CollUtil.isEmpty(deptRelations)) {
+//            return page;
+//        }
+//        queryDeptIds.addAll(jyEntRelationDeptIds);
+//
+//        Set<Integer> subDeptIds = deptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toSet());
+//        queryDeptIds.addAll(subDeptIds);
+//        // 查询下级企业的信息
+//        List<SysDeptRelation> subRelations = deptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
+//                .in(SysDeptRelation::getAncestor, subDeptIds));
+//        if (CollUtil.isNotEmpty(subRelations)) {
+//            Set<Integer> sub1DeptIds = subRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toSet());
+//            queryDeptIds.addAll(sub1DeptIds);
+//            // 查询下下级企业的信息
+//            List<SysDeptRelation> sub2Relations = deptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
+//                    .in(SysDeptRelation::getAncestor, sub1DeptIds));
+//            if (CollUtil.isNotEmpty(sub2Relations)) {
+//                Set<Integer> sub2DeptIds = sub2Relations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toSet());
+//                queryDeptIds.addAll(sub2DeptIds);
+//            }
+//        }
+//
+//        // 企业名称查询过滤
+//        if (StrUtil.isNotEmpty(toScorePackagePage.getDeptName())) {
+//            List<SysDept> queryLikeDepts = deptService.list(Wrappers.<SysDept>lambdaQuery()
+//                    .like(SysDept::getName, toScorePackagePage.getDeptName()));
+//            if (CollUtil.isEmpty(queryLikeDepts)) {
+//                return page;
+//            }
+//            Set<Integer> likeDeptIds = queryLikeDepts.stream().map(SysDept::getDeptId).collect(Collectors.toSet());
+//            queryDeptIds.retainAll(likeDeptIds);
+//        }
+//
+//        IPage<SysDeptInvoiceRelationVO> relationVOIPage =
+//                deptInvoiceRelationMapper.pageInvoiceScorePacakgeRelation(new Page<>(page.getCurrent(), page.getSize()), toScorePackagePage, queryDeptIds);
+//
+//        List<SysDeptInvoiceRelationVO> records = relationVOIPage.getRecords();
+//        if (CollUtil.isEmpty(records)) {
+//            return page;
+//        }
+//
+//        // 积分包接单用户map
+//        Map<String, String> packageUsersMap = new HashMap<>();
+//        // 查领包记录
+//        Set<String> packageIds = records.stream().map(SysDeptInvoiceRelationVO::getScorePackageId).collect(Collectors.toSet());
+//        List<WmScorePackageStatus> scorePackageStatusList = scorePackageStatusMapper.selectList(Wrappers.<WmScorePackageStatus>lambdaQuery()
+//                .in(WmScorePackageStatus::getPackageId, packageIds)
+//                .eq(WmScorePackageStatus::getStatus, PackageStatusEnum.APPROVED.val()));
+//        if (CollUtil.isNotEmpty(scorePackageStatusList)) {
+//            // 查询领包记录的所有用户
+//            Set<String> statusUserIds = scorePackageStatusList.stream().map(WmScorePackageStatus::getUserId).collect(Collectors.toSet());
+//            List<SysUser> statusUsers = userService.listByIds(statusUserIds);
+//            // 转为map(key-积分包id,value-领包用户逗号分隔)
+//            Map<Integer, String> statusUserMap = statusUsers.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getRealname));
+//            packageUsersMap = scorePackageStatusList.stream()
+//                    .collect(Collectors.groupingBy(WmScorePackageStatus::getPackageId,
+//                            Collectors.mapping(wmScorePackageStatus ->
+//                                    statusUserMap.getOrDefault(Integer.parseInt(wmScorePackageStatus.getUserId()), ""), Collectors.joining(","))));
+//        }
+//
+//        // 查询积分包涉及的企业
+//        Set<Integer> deptIds = records.stream().map(SysDeptInvoiceRelationVO::getDeptId).collect(Collectors.toSet());
+//        List<SysDept> depts = deptService.listByIds(deptIds);
+//        Map<Integer, String> deptMap = depts.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getName));
+//
+//        Map<String, String> finalPackageUsersMap = packageUsersMap;
+//        records.forEach(vo -> {
+//            vo.setDeptName(deptMap.getOrDefault(vo.getDeptId(), ""));
+//            vo.setTaskUsers(finalPackageUsersMap.getOrDefault(vo.getScorePackageId(), ""));
+//            vo.setInvoiceStatusStr(vo.getInvoiceStatus().getDescription());
+//        });
+//
+//        return relationVOIPage;
+//    }
+
+    /**
+     * 平台财务管理-开票列表
+     *
+     * @param page 分页参数
+     * @param toInvoicePage 请求参数
+     * @return 响应结果
+     */
+    @Override
+    public IPage<SysDeptInvoiceVO> pageInvoiceForAdmin(Page<SysDeptInvoiceVO> page, SysDeptInvoiceRequest.ToInvoicePage toInvoicePage) {
+        LambdaQueryWrapper<SysDeptInvoice> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysDeptInvoice::getDelFlag, DelEnum.NOT_DEL.val());
+        if (toInvoicePage.getApprovalStatus() != null) {
+            queryWrapper.eq(SysDeptInvoice::getApprovalStatus, toInvoicePage.getApprovalStatus());
+        }
+        if (toInvoicePage.getCreateTime() != null && toInvoicePage.getCreateTime().length == 2) {
+            queryWrapper.between(SysDeptInvoice::getCreateTime, toInvoicePage.getCreateTime()[0], toInvoicePage.getCreateTime()[1]);
+        }
+        if (StrUtil.isNotBlank(toInvoicePage.getDeptName())) {
+            List<SysDept> queryLikeDepts = deptService.list(Wrappers.<SysDept>lambdaQuery()
+                    .like(SysDept::getName, toInvoicePage.getDeptName()));
+            if (CollUtil.isEmpty(queryLikeDepts)) {
+                return page;
+            }
+            Set<Integer> likeDeptIds = queryLikeDepts.stream().map(SysDept::getDeptId).collect(Collectors.toSet());
+            queryWrapper.in(SysDeptInvoice::getDeptId, likeDeptIds);
+        }
+
+        Page<SysDeptInvoice> invoicePage = this.page(new Page<>(page.getCurrent(), page.getSize()), queryWrapper);
+
+        if (CollUtil.isEmpty(invoicePage.getRecords())) {
+            return page;
+        }
+
+        // 查询发票列表涉及的企业
+        Set<Integer> deptIds = invoicePage.getRecords().stream().map(SysDeptInvoice::getDeptId).collect(Collectors.toSet());
+        List<SysDept> depts = deptService.listByIds(deptIds);
+        Map<Integer, String> deptMap = depts.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getName));
+
+        List<SysDeptInvoiceVO> voList = new ArrayList<>();
+        invoicePage.getRecords().forEach(sysDeptInvoice -> {
+            SysDeptInvoiceVO deptInvoiceVO = BeanUtil.copyProperties(sysDeptInvoice, SysDeptInvoiceVO.class);
+            deptInvoiceVO.setDeptName(deptMap.getOrDefault(sysDeptInvoice.getDeptId(), ""));
+            voList.add(deptInvoiceVO);
+        });
+
+        page.setPages(invoicePage.getPages());
+        page.setTotal(invoicePage.getTotal());
+        page.setRecords(voList);
+
+        return page;
+    }
+
+//    /**
+//     * 园区-开票列表
+//     *
+//     * @param page 分页参数
+//     * @param toInvoicePage 请求参数
+//     * @return 响应结果
+//     */
+//    @Override
+//    public IPage<SysDeptInvoiceVO> pageInvoiceRecordForPark(Page<SysDeptInvoiceVO> page, SysDeptInvoiceRequest.ToInvoicePage toInvoicePage) {
+//        Integer deptId = SecurityUtils.getUser().getDeptId();
+//
+//        LambdaQueryWrapper<SysDeptInvoice> queryWrapper = Wrappers.lambdaQuery();
+//        queryWrapper.eq(SysDeptInvoice::getDelFlag, DelEnum.NOT_DEL.val());
+//        queryWrapper.eq(SysDeptInvoice::getDeptId, deptId);
+//        if (toInvoicePage.getApprovalStatus() != null) {
+//            queryWrapper.eq(SysDeptInvoice::getApprovalStatus, toInvoicePage.getApprovalStatus());
+//        }
+//        if (toInvoicePage.getCreateTime() != null && toInvoicePage.getCreateTime().length == 2) {
+//            queryWrapper.between(SysDeptInvoice::getCreateTime, toInvoicePage.getCreateTime()[0], toInvoicePage.getCreateTime()[1]);
+//        }
+//        if (StrUtil.isNotBlank(toInvoicePage.getDeptName())) {
+//            List<SysDept> queryLikeDepts = deptService.list(Wrappers.<SysDept>lambdaQuery()
+//                    .like(SysDept::getName, toInvoicePage.getDeptName()));
+//            if (CollUtil.isEmpty(queryLikeDepts)) {
+//                return page;
+//            }
+//            Set<Integer> likeDeptIds = queryLikeDepts.stream().map(SysDept::getDeptId).collect(Collectors.toSet());
+//            queryWrapper.in(SysDeptInvoice::getDeptId, likeDeptIds);
+//        }
+//
+//        Page<SysDeptInvoice> invoicePage = this.page(new Page<>(page.getCurrent(), page.getSize()), queryWrapper);
+//
+//        if (CollUtil.isEmpty(invoicePage.getRecords())) {
+//            return page;
+//        }
+//
+//        // 查询发票列表涉及的企业
+//        SysDept dept = deptService.getById(deptId);
+//
+//        List<SysDeptInvoiceVO> voList = new ArrayList<>();
+//        invoicePage.getRecords().forEach(sysDeptInvoice -> {
+//            SysDeptInvoiceVO deptInvoiceVO = BeanUtil.copyProperties(sysDeptInvoice, SysDeptInvoiceVO.class);
+//            deptInvoiceVO.setDeptName(dept.getName());
+//            voList.add(deptInvoiceVO);
+//        });
+//
+//        page.setPages(invoicePage.getPages());
+//        page.setTotal(invoicePage.getTotal());
+//        page.setRecords(voList);
+//
+//        return page;
+//    }
+
+    /**
+     * 平台财务-关联积分包列表
+     *
+     * @param page   分页参数
+     * @param invoiceId 企业开票表ID
+     * @return 响应结果
+     */
+    @Override
+    public IPage<SysDeptInvoiceRelationVO> pageInvoice(Page<SysDeptInvoiceRelationVO> page, Integer invoiceId) {
+
+        IPage<SysDeptInvoiceRelationVO> relationVOIPage =
+                deptInvoiceRelationMapper.pageInvoiceScorePacakgeRelation2(new Page<>(page.getCurrent(), page.getSize()), invoiceId);
+
+        List<SysDeptInvoiceRelationVO> records = relationVOIPage.getRecords();
+        if (CollUtil.isEmpty(records)) {
+            return page;
+        }
+
+        // 积分包接单用户map
+        Map<String, String> packageUsersMap = new HashMap<>();
+        // 查领包记录
+        Set<String> packageIds = records.stream().map(SysDeptInvoiceRelationVO::getScorePackageId).collect(Collectors.toSet());
+        List<WmScorePackageStatus> scorePackageStatusList = scorePackageStatusMapper.selectList(Wrappers.<WmScorePackageStatus>lambdaQuery()
+                .in(WmScorePackageStatus::getPackageId, packageIds)
+                .eq(WmScorePackageStatus::getStatus, PackageStatusEnum.APPROVED.val()));
+        if (CollUtil.isNotEmpty(scorePackageStatusList)) {
+            // 查询领包记录的所有用户
+            Set<String> statusUserIds = scorePackageStatusList.stream().map(WmScorePackageStatus::getUserId).collect(Collectors.toSet());
+            List<SysUser> statusUsers = userService.listByIds(statusUserIds);
+            // 转为map(key-积分包id,value-领包用户逗号分隔)
+            Map<Integer, String> statusUserMap = statusUsers.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getRealname));
+            packageUsersMap = scorePackageStatusList.stream()
+                    .collect(Collectors.groupingBy(WmScorePackageStatus::getPackageId,
+                            Collectors.mapping(wmScorePackageStatus ->
+                                    statusUserMap.getOrDefault(Integer.parseInt(wmScorePackageStatus.getUserId()), ""), Collectors.joining(","))));
+        }
+
+        // 查询积分包涉及的企业
+        Set<Integer> deptIds = records.stream().map(SysDeptInvoiceRelationVO::getDeptId).collect(Collectors.toSet());
+        List<SysDept> depts = deptService.listByIds(deptIds);
+        Map<Integer, String> deptMap = depts.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getName));
+
+        Map<String, String> finalPackageUsersMap = packageUsersMap;
+        records.forEach(vo -> {
+            vo.setDeptName(deptMap.getOrDefault(vo.getDeptId(), ""));
+            vo.setTaskUsers(finalPackageUsersMap.getOrDefault(vo.getScorePackageId(), ""));
+            vo.setInvoiceStatusStr(vo.getInvoiceStatus().getDescription());
+            vo.setScorePackageStatusStr(Objects.requireNonNull(ScorePackageStatusEnum.getByVal(vo.getScorePackageStatus())).getDesc());
+        });
+
+        return relationVOIPage;
+    }
+
+    /**
+     * 可开票积分
+     *
+     * @param deptId 企业id
+     * @return 可开票积分记录
+     */
+    @Override
+    public List<SysDeptInvoiceRelationVO> listToInvoiceScore(Integer deptId) {
+        Set<Integer> queryDeptIds = new HashSet<>();
+        // 查询关联的企业
+        List<SysDeptRelation> deptRelations = deptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
+                .eq(SysDeptRelation::getAncestor, deptId)
+                .ne(SysDeptRelation::getDescendant, deptId));
+        if (CollUtil.isNotEmpty(deptRelations)) {
+            Set<Integer> subDeptIds = deptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toSet());
+            queryDeptIds.addAll(subDeptIds);
+            // 查询下级企业的信息
+            List<SysDeptRelation> subRelations = deptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
+                    .in(SysDeptRelation::getAncestor, subDeptIds));
+            if (CollUtil.isNotEmpty(subRelations)) {
+                Set<Integer> sub1DeptIds = subRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toSet());
+                queryDeptIds.addAll(sub1DeptIds);
+                // 查询下下级企业的信息
+                List<SysDeptRelation> sub2Relations = deptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
+                        .in(SysDeptRelation::getAncestor, sub1DeptIds));
+                if (CollUtil.isNotEmpty(sub2Relations)) {
+                    Set<Integer> sub2DeptIds = sub2Relations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toSet());
+                    queryDeptIds.addAll(sub2DeptIds);
+                }
+            }
+        }
+
+        SysDeptInvoiceRequest.ToScorePackagePage toScorePackagePage = new SysDeptInvoiceRequest.ToScorePackagePage();
+        toScorePackagePage.setInvoiceStatus(InvoiceStatus.NOT_APPLY);
+
+        return deptInvoiceRelationMapper.listInvoiceScorePacakgeRelation(toScorePackagePage, queryDeptIds);
+    }
+
+    /**
+     * 开发票
+     *
+     * @param toInvoice 开票参数
+     * @return 响应结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean toInvoice(SysDeptInvoiceRequest.ToInvoice toInvoice) {
+        Integer deptId = SecurityUtils.getUser().getDeptId();
+        Integer userId = SecurityUtils.getUser().getId();
+
+        String[] packageIds = toInvoice.getPackageIds();
+        Set<String> packageIdSet = Stream.of(packageIds).collect(Collectors.toSet());
+        int relationCount = deptInvoiceRelationService.count(Wrappers.<SysDeptInvoiceRelation>lambdaQuery()
+                .in(SysDeptInvoiceRelation::getPackageId, packageIdSet)
+                .eq(SysDeptInvoiceRelation::getDelFlag, DelEnum.NOT_DEL.val()));
+        if (relationCount > 0) {
+            throw new RuntimeException("请选择开票状态为未申请的数据");
+        }
+
+        List<WmScorePackage> scorePackages = scorePackageMapper.selectBatchIds(packageIdSet);
+
+        // 选择开票的总积分
+        int totalScore = scorePackages.stream().mapToInt(WmScorePackage::getScore).sum();
+        // 计算开票金额
+        SysDeptRecharge deptRecharge = deptRechargeMapper.selectOne(Wrappers.<SysDeptRecharge>lambdaQuery()
+                .eq(SysDeptRecharge::getDeptId, deptId));
+        if (deptRecharge == null || deptRecharge.getServiceCharge() == null) {
+            throw new RuntimeException("没有配置服务费率");
+        }
+        // 开票金额 = 开票积分 * (服务费率/100)
+        BigDecimal invoiceAmount = deptRecharge.getServiceCharge().divide(new BigDecimal("100.00"))
+                .multiply(BigDecimal.valueOf(totalScore)).setScale(2, RoundingMode.HALF_EVEN);
+        // 保存开票信息
+        SysDeptInvoice deptInvoice = new SysDeptInvoice();
+        deptInvoice.setDeptId(deptId);
+        deptInvoice.setInvoiceType(toInvoice.getInvoiceType());
+        deptInvoice.setAddress(toInvoice.getAddress());
+        deptInvoice.setAddresseeName(toInvoice.getAddresseeName());
+        deptInvoice.setAddresseePhone(toInvoice.getAddresseePhone());
+        deptInvoice.setApprovalStatus(InvoiceApprovalStatus.PENDING);
+        deptInvoice.setRelationPackageNumber(scorePackages.size());
+        deptInvoice.setRelationPackageScore(totalScore);
+        deptInvoice.setInvoiceAmount(invoiceAmount);
+        this.save(deptInvoice);
+
+        // 保存开票积分包关联信息
+        Set<SysDeptInvoiceRelation> invoiceRelations = scorePackages.stream().map(scorePackage -> {
+            SysDeptInvoiceRelation invoiceRelation = new SysDeptInvoiceRelation();
+            invoiceRelation.setDeptId(Integer.valueOf(scorePackage.getDeptId()));
+            invoiceRelation.setInvoiceId(deptInvoice.getId());
+            invoiceRelation.setInvoiceStatus(InvoiceStatus.PENDING);
+            invoiceRelation.setCreateUser(userId);
+            invoiceRelation.setPackageId(scorePackage.getId());
+            return invoiceRelation;
+        }).collect(Collectors.toSet());
+        boolean b = deptInvoiceRelationService.saveBatch(invoiceRelations);
+        if (!b) {
+            throw new RuntimeException("保存失败");
+        }
+
+        // 缓存信息
+        String cacheKey = CacheConstants.INVOICE_DEPT_KEY + deptId;
+        redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(deptInvoice));
+
+        return Boolean.TRUE;
+    }
+
+    /**
+     * 开票审核
+     *
+     * @param toApprove 开票参数
+     * @return 响应结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean toApprove(SysDeptInvoiceRequest.ToApprove toApprove) {
+        Integer userId = SecurityUtils.getUser().getId();
+        LocalDateTime now = LocalDateTime.now();
+
+        // 查询开票表
+        SysDeptInvoice deptInvoice = this.getById(toApprove.getInvoiceId());
+        if (!InvoiceApprovalStatus.PENDING.equals(deptInvoice.getApprovalStatus())) {
+            throw new RuntimeException("开票状态不正确");
+        }
+        // 查询开票积分包关联表
+        List<SysDeptInvoiceRelation> deptInvoiceRelations = deptInvoiceRelationService.list(Wrappers.<SysDeptInvoiceRelation>lambdaQuery()
+                .eq(SysDeptInvoiceRelation::getInvoiceId, toApprove.getInvoiceId())
+                .eq(SysDeptInvoiceRelation::getDelFlag, DelEnum.NOT_DEL.val()));
+
+        // 更新开票积分包关联表
+        List<SysDeptInvoiceRelation> updateRelationList = new ArrayList<>();
+        deptInvoiceRelations.forEach(relation -> {
+            // 校验
+            if (!InvoiceStatus.PENDING.equals(relation.getInvoiceStatus())) {
+                throw new RuntimeException("关联积分包的审核状态不正确");
+            }
+            SysDeptInvoiceRelation updateRelation = new SysDeptInvoiceRelation();
+            updateRelation.setId(relation.getId());
+            updateRelation.setInvoiceStatus(InvoiceStatus.getByApproveStatus(toApprove.getApprovalStatus()));
+            updateRelation.setInvoiceTime(now);
+            updateRelation.setUpdateTime(now);
+            updateRelation.setUpdateUser(userId);
+            updateRelationList.add(updateRelation);
+        });
+        boolean b = deptInvoiceRelationService.updateBatchById(updateRelationList);
+        if (!b) {
+            throw new RuntimeException("更新失败");
+        }
+
+        // 更新开票信息
+        SysDeptInvoice updateDeptInvoice = new SysDeptInvoice();
+        updateDeptInvoice.setId(toApprove.getInvoiceId());
+        updateDeptInvoice.setApprovalStatus(toApprove.getApprovalStatus());
+        updateDeptInvoice.setApprovalTime(now);
+        updateDeptInvoice.setUpdateTime(now);
+        updateDeptInvoice.setUpdateUser(userId);
+        this.updateById(updateDeptInvoice);
+
+        return Boolean.TRUE;
+    }
+}
+
+
+
+

+ 232 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptRechargeRecordServiceImpl.java

@@ -0,0 +1,232 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.qunzhixinxi.hnqz.admin.api.entity.SysDept;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackage;
+import com.qunzhixinxi.hnqz.admin.entity.WmScorePackageStatus;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.DeptLevelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.PackageStatusEnum;
+import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageMapper;
+import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageStatusMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRechargeRecord;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordPackageType;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptRechargeRecordMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptRechargeRecordService;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeRecordForDeptVO;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeRecordVO;
+import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
+import com.qunzhixinxi.hnqz.admin.service.SysUserService;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_recharge_record(积分充值/使用记录表)】的数据库操作Service实现
+* @createDate 2023-06-12 14:40:23
+*/
+@Service
+@AllArgsConstructor
+public class SysDeptRechargeRecordServiceImpl extends ServiceImpl<SysDeptRechargeRecordMapper, SysDeptRechargeRecord>
+    implements SysDeptRechargeRecordService {
+
+    private final SysDeptService deptService;
+    private final WmScorePackageMapper wmScorePackageMapper;
+    private final SysUserService userService;
+    private final WmScorePackageStatusMapper wmScorePackageStatusMapper;
+
+    /**
+     * 充值、分配记录
+     *
+     * @param page       分页参数
+     * @param deptId     企业id
+     * @return 分页结果
+     */
+    @Override
+    public IPage<SysDeptRechargeRecordVO> pageRechargeRecord(Page<SysDeptRechargeRecordVO> page, Integer deptId) {
+        LambdaQueryWrapper<SysDeptRechargeRecord> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysDeptRechargeRecord::getDeptId, deptId);
+        queryWrapper.eq(SysDeptRechargeRecord::getDelFlag, DelEnum.NOT_DEL.val());
+        queryWrapper.orderByDesc(SysDeptRechargeRecord::getCreateTime);
+        Page<SysDeptRechargeRecord> recordPage = this.page(new Page<>(page.getCurrent(), page.getSize()), queryWrapper);
+
+        if (CollUtil.isNotEmpty(recordPage.getRecords())) {
+            // 查询企业
+            Set<Integer> deptIds = recordPage.getRecords().stream().map(SysDeptRechargeRecord::getDeptId).collect(Collectors.toSet());
+            List<SysDept> sysDepts = deptService.listByIds(deptIds);
+            Map<Integer, SysDept> deptMap = sysDepts.stream().collect(Collectors.toMap(SysDept::getDeptId, Function.identity()));
+            // 查询用户
+            Set<Integer> userIds = recordPage.getRecords().stream().map(SysDeptRechargeRecord::getCreateUser).collect(Collectors.toSet());
+            List<SysUser> users = userService.listByIds(userIds);
+            Map<Integer, String> userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getRealname));
+
+            List<SysDeptRechargeRecordVO> recordVOList = new ArrayList<>();
+            recordPage.getRecords().forEach(record -> {
+                SysDeptRechargeRecordVO recordVO = BeanUtil.copyProperties(record, SysDeptRechargeRecordVO.class);
+                SysDept dept = deptMap.get(record.getDeptId());
+                if (dept != null) {
+                    recordVO.setDeptName(dept.getName());
+                    recordVO.setDeptLevel(dept.getLevel());
+                    recordVO.setDeptLevelStr(Objects.requireNonNull(DeptLevelEnum.getEnumByVal(dept.getLevel())).getName());
+                }
+                recordVO.setCreaUserStr(userMap.get(record.getCreateUser()));
+                recordVOList.add(recordVO);
+            });
+
+            page.setPages(recordPage.getPages());
+            page.setRecords(recordVOList);
+            page.setTotal(recordPage.getTotal());
+        }
+
+        return page;
+    }
+
+    /**
+     * 分配、发包记录(企业)
+     *
+     * @param page       分页参数
+     * @param type       操作类型
+     * @param createTime 创建时间范围
+     * @return 分页结果
+     */
+    @Override
+    public IPage<SysDeptRechargeRecordForDeptVO> pageRecordForDept(Page<SysDeptRechargeRecordForDeptVO> page, RechargeRecordType type, LocalDateTime[] createTime) {
+        Integer deptId = SecurityUtils.getUser().getDeptId();
+        // 是否管理员或平台管理员
+        boolean isAdmin = CollUtil.containsAny(SecurityUtils.getRoles(), Stream.of(1, 2).collect(Collectors.toList()));
+
+        LambdaQueryWrapper<SysDeptRechargeRecord> queryWrapper = Wrappers.lambdaQuery();
+        if (!isAdmin) {
+            queryWrapper.eq(SysDeptRechargeRecord::getDeptId, deptId);
+        }
+        if (type != null) {
+            queryWrapper.eq(SysDeptRechargeRecord::getType, type);
+        }
+        if (createTime != null && createTime.length == 2) {
+            queryWrapper.between(SysDeptRechargeRecord::getCreateTime, createTime[0], createTime[1]);
+        }
+
+        queryWrapper.eq(SysDeptRechargeRecord::getDelFlag, DelEnum.NOT_DEL.val());
+        queryWrapper.orderByDesc(SysDeptRechargeRecord::getCreateTime);
+        Page<SysDeptRechargeRecord> recordPage = this.page(new Page<>(page.getCurrent(), page.getSize()), queryWrapper);
+
+        if (CollUtil.isNotEmpty(recordPage.getRecords())) {
+            // 查询企业
+            SysDept dept = deptService.getById(deptId);
+            // 查询所有企业
+            List<SysDept> depts = deptService.list();
+            Map<Integer, String> deptMap = depts.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getName));
+            // 查询用户
+            Set<Integer> userIds = recordPage.getRecords().stream().map(SysDeptRechargeRecord::getCreateUser).collect(Collectors.toSet());
+            List<SysUser> users = userService.listByIds(userIds);
+            Map<Integer, String> userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getRealname));
+            // 查询发放的积分包
+            List<WmScorePackage> scorePackages = wmScorePackageMapper.selectList(Wrappers.<WmScorePackage>lambdaQuery()
+                    .select(WmScorePackage::getId, WmScorePackage::getScorePackageName)
+                    .eq(WmScorePackage::getDelFlag, DelEnum.NOT_DEL.val())
+                    .eq(WmScorePackage::getSendPackageDeptId, deptId));
+            // 积分包map
+            Map<String, String> packageMap = new HashMap<>();
+            // 积分包接单用户map
+            Map<String, String> packageUsersMap = new HashMap<>();
+            // 积分包子包企业map
+            Map<String, Set<String>> scorePackageToEntsMap = new HashMap<>();
+            if (CollUtil.isNotEmpty(scorePackages)) {
+                packageMap = scorePackages.stream().collect(Collectors.toMap(WmScorePackage::getId, WmScorePackage::getScorePackageName));
+                // 查领包记录
+                Set<String> packageIds = scorePackages.stream().map(WmScorePackage::getId).collect(Collectors.toSet());
+                List<WmScorePackageStatus> scorePackageStatusList = wmScorePackageStatusMapper.selectList(Wrappers.<WmScorePackageStatus>lambdaQuery()
+                        .in(WmScorePackageStatus::getPackageId, packageIds)
+                        .eq(WmScorePackageStatus::getStatus, PackageStatusEnum.APPROVED.val()));
+                if (CollUtil.isNotEmpty(scorePackageStatusList)) {
+                    // 查询领包记录的所有用户
+                    Set<String> statusUserIds = scorePackageStatusList.stream().map(WmScorePackageStatus::getUserId).collect(Collectors.toSet());
+                    List<SysUser> statusUsers = userService.listByIds(statusUserIds);
+                    // 转为map(key-积分包id,value-领包用户逗号分隔)
+                    Map<Integer, String> statusUserMap = statusUsers.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getRealname));
+                    packageUsersMap = scorePackageStatusList.stream()
+                            .collect(Collectors.groupingBy(WmScorePackageStatus::getPackageId,
+                                    Collectors.mapping(wmScorePackageStatus ->
+                                            statusUserMap.getOrDefault(Integer.parseInt(wmScorePackageStatus.getUserId()), ""), Collectors.joining(","))));
+                }
+                // 查询积分包的子包
+                List<WmScorePackage> subScorePackages = wmScorePackageMapper.selectList(Wrappers.<WmScorePackage>lambdaQuery()
+                        .in(WmScorePackage::getRelationScoreId, packageIds));
+                if (CollUtil.isNotEmpty(subScorePackages)) {
+                    // 查询子包的所有企业
+                    List<SysDept> subPackageDepts = deptService.listByIds(subScorePackages.stream()
+                            .map(wmScorePackage -> Integer.parseInt(wmScorePackage.getSendPackageDeptId())).collect(Collectors.toSet()));
+                    // 转为map(key-积分包id,value-子包企业逗号分隔)
+                    Map<Integer, String> subPackageDeptsMap = subPackageDepts.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getName));
+                    scorePackageToEntsMap = subScorePackages.stream()
+                            .collect(Collectors.groupingBy(WmScorePackage::getRelationScoreId,
+                                    Collectors.mapping(wmScorePackage ->
+                                            subPackageDeptsMap.getOrDefault(Integer.parseInt(wmScorePackage.getSendPackageDeptId()), ""), Collectors.toSet())));
+                }
+            }
+
+
+            List<SysDeptRechargeRecordForDeptVO> recordVOList = new ArrayList<>();
+            Map<String, String> finalPackageUsersMap = packageUsersMap;
+            Map<String, Set<String>> finalScorePackageToEntsMap = scorePackageToEntsMap;
+            Map<String, String> finalPackageMap = packageMap;
+            recordPage.getRecords().forEach(record -> {
+                SysDeptRechargeRecordForDeptVO recordVO = BeanUtil.copyProperties(record, SysDeptRechargeRecordForDeptVO.class);
+                if (dept != null) {
+                    recordVO.setDeptName(dept.getName());
+                    recordVO.setDeptLevel(dept.getLevel());
+                    recordVO.setDeptLevelStr(Objects.requireNonNull(DeptLevelEnum.getEnumByVal(dept.getLevel())).getName());
+                }
+                recordVO.setCreaUserStr(userMap.get(record.getCreateUser()));
+                recordVO.setOperatingTarget(recordVO.getDeptName());
+                // 关联对象
+                if (RechargeRecordType.SEND_PACKAGE_DEPT.equals(record.getType()) || RechargeRecordType.SEND_PACKAGE_PERSONAL.equals(record.getType())
+                        || RechargeRecordType.RECOVERY.equals(record.getType())) {
+                    if (RechargeRecordPackageType.TO_PERSON.equals(record.getPackageType())) {
+                        recordVO.setOperatingTarget(finalPackageUsersMap.get(record.getPackageId()));
+                    } else {
+                        recordVO.setOperatingTarget(String.join(",", finalScorePackageToEntsMap.getOrDefault(record.getPackageId(), Collections.emptySet())));
+                    }
+                    // 积分包名称
+                    recordVO.setScorePackageName(finalPackageMap.get(record.getPackageId()));
+                } else {
+                    if (record.getRelationDeptId() != null) {
+                        recordVO.setOperatingTarget(deptMap.get(record.getRelationDeptId()));
+                    }
+                }
+                recordVOList.add(recordVO);
+            });
+
+            page.setPages(recordPage.getPages());
+            page.setRecords(recordVOList);
+            page.setTotal(recordPage.getTotal());
+        }
+
+        return page;
+    }
+}
+
+
+
+

+ 251 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/service/impl/SysDeptRechargeServiceImpl.java

@@ -0,0 +1,251 @@
+package com.qunzhixinxi.hnqz.admin.recharge.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.qunzhixinxi.hnqz.admin.api.entity.SysDept;
+import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
+import com.qunzhixinxi.hnqz.admin.enums.DeptLevelEnum;
+import com.qunzhixinxi.hnqz.admin.recharge.dto.SysDeptRechargeRequest;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRecharge;
+import com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptRechargeRecord;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import com.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptRechargeMapper;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptRechargeRecordService;
+import com.qunzhixinxi.hnqz.admin.recharge.service.SysDeptRechargeService;
+import com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptRechargeVO;
+import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+* @author snows
+* @description 针对表【sys_dept_recharge(积分充值表)】的数据库操作Service实现
+* @createDate 2023-06-12 10:47:24
+*/
+@Service
+@AllArgsConstructor
+public class SysDeptRechargeServiceImpl extends ServiceImpl<SysDeptRechargeMapper, SysDeptRecharge>
+    implements SysDeptRechargeService {
+
+    private final SysDeptService deptService;
+    private final SysDeptRechargeRecordService deptRechargeRecordService;
+
+    /**
+     * 分页查询
+     *
+     * @param page 分页参数
+     * @param toPage 条件参数
+     * @return 分页结果
+     */
+    @Override
+    public IPage<SysDeptRechargeVO> pageRechargeForAdmin(Page<SysDeptRechargeVO> page, SysDeptRechargeRequest.ToPage toPage) {
+        LambdaQueryWrapper<SysDept> queryWrapper = Wrappers.lambdaQuery();
+        if (StrUtil.isNotBlank(toPage.getDeptName())) {
+            queryWrapper.like(SysDept::getName, toPage.getDeptName());
+        }
+        if (toPage.getDeptLevel() != null) {
+            queryWrapper.eq(SysDept::getLevel, toPage.getDeptLevel());
+        }
+        // 只显示除管理员的企业
+        queryWrapper.ne(SysDept::getLevel, DeptLevelEnum.ADMIN.getVal());
+
+        Page<SysDept> deptPage = deptService.page(new Page<>(page.getCurrent(), page.getSize()), queryWrapper);
+
+        List<SysDeptRechargeVO> rechargeVOList = new ArrayList<>();
+        if (CollUtil.isEmpty(deptPage.getRecords())) {
+            return page;
+        }
+
+        // 查询企业积分充值表
+        List<SysDeptRecharge> deptRecharges = this.list(Wrappers.<SysDeptRecharge>lambdaQuery()
+                .eq(SysDeptRecharge::getDelFlag, DelEnum.NOT_DEL.val()));
+        Map<Integer, SysDeptRecharge> deptRechargeMap = new HashMap<>();
+        if (CollUtil.isNotEmpty(deptRecharges)) {
+            deptRechargeMap = deptRecharges.stream()
+                    .collect(Collectors.toMap(SysDeptRecharge::getDeptId, Function.identity()));
+        }
+        // 查询积分充值记录表
+        List<SysDeptRechargeRecord> usedRecords = deptRechargeRecordService.list(Wrappers.<SysDeptRechargeRecord>lambdaQuery()
+                .eq(SysDeptRechargeRecord::getType, RechargeRecordType.RECHARGE)
+                .eq(SysDeptRechargeRecord::getDelFlag, DelEnum.NOT_DEL.val()));
+        Map<Integer, Integer> usedRecordsMap = new HashMap<>();
+        if (CollUtil.isNotEmpty(usedRecords)) {
+            usedRecordsMap = usedRecords.stream()
+                    .collect(Collectors.groupingBy(SysDeptRechargeRecord::getDeptId, Collectors.summingInt(SysDeptRechargeRecord::getChangeScore)));
+        }
+
+        Map<Integer, SysDeptRecharge> finalDeptRechargeMap = deptRechargeMap;
+        Map<Integer, Integer> finalUsedRecordsMap = usedRecordsMap;
+        deptPage.getRecords().forEach(sysDept -> {
+            SysDeptRechargeVO deptRechargeVO = new SysDeptRechargeVO();
+            deptRechargeVO.setDeptName(sysDept.getName());
+            deptRechargeVO.setDeptId(sysDept.getDeptId());
+            deptRechargeVO.setDeptLevel(sysDept.getLevel());
+            deptRechargeVO.setDeptLevelStr(Objects.requireNonNull(DeptLevelEnum.getEnumByVal(sysDept.getLevel())).getName());
+            SysDeptRecharge deptRecharge = finalDeptRechargeMap.get(sysDept.getDeptId());
+            if (deptRecharge != null) {
+                deptRechargeVO.setId(deptRecharge.getId());
+                deptRechargeVO.setScore(deptRecharge.getScore());
+                deptRechargeVO.setBalance(deptRecharge.getBalance());
+                deptRechargeVO.setServiceCharge(deptRecharge.getServiceCharge());
+                deptRechargeVO.setOverdrawAmount(deptRecharge.getOverdrawAmount());
+                deptRechargeVO.setOverdrawScore(deptRecharge.getOverdrawScore());
+                deptRechargeVO.setPermissions(deptRecharge.getPermissions());
+                // 根据充值记录计算
+                Integer totalRechargeScore = finalUsedRecordsMap.getOrDefault(sysDept.getDeptId(), 0);
+                deptRechargeVO.setTotalRechargeScore(totalRechargeScore);
+                deptRechargeVO.setTotalInvoiceScore(0);
+                deptRechargeVO.setTotalInvoiceAmount(BigDecimal.ZERO);
+            }
+            rechargeVOList.add(deptRechargeVO);
+        });
+
+        page.setRecords(rechargeVOList);
+        page.setTotal(deptPage.getTotal());
+        page.setPages(deptPage.getPages());
+
+        return page;
+    }
+
+    /**
+     * 充值
+     *
+     * @param toRecharge 充值参数
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean recharge(SysDeptRechargeRequest.ToRecharge toRecharge) {
+
+        Integer operator = SecurityUtils.getUser().getId();
+        Integer deptId = SecurityUtils.getUser().getDeptId();
+
+        // 更新充值数据
+        SysDeptRecharge deptRecharge = this.getOne(Wrappers.<SysDeptRecharge>lambdaQuery()
+                .eq(SysDeptRecharge::getDeptId, toRecharge.getDeptId())
+                .eq(SysDeptRecharge::getDelFlag, DelEnum.NOT_DEL.val()));
+        BigDecimal currentBalance = null;
+        int currentScore = 0;
+        if (deptRecharge == null) {
+            throw new RuntimeException("费率不存在");
+        } else {
+            // 基于 充值金额 计算
+            // 充值积分 = 充值金额 / (服务费率/100)
+            BigDecimal rechargeScore = toRecharge.getRechargeAmount().divide(deptRecharge.getServiceCharge()
+                            .divide(new BigDecimal("100.00")), RoundingMode.HALF_EVEN)
+                    .setScale(0, RoundingMode.UP);
+
+            if (!toRecharge.getRechargeScore().equals(rechargeScore.intValue())) {
+                throw new RuntimeException("充值积分不正确");
+            }
+            // 计算更新金额
+            currentBalance  = toRecharge.getRechargeAmount().add(deptRecharge.getBalance());
+            currentScore = rechargeScore.intValue() + deptRecharge.getScore();
+            // 更新
+            boolean update = this.update(Wrappers.<SysDeptRecharge>lambdaUpdate()
+                    .eq(SysDeptRecharge::getId, deptRecharge.getId())
+                    .eq(SysDeptRecharge::getVersion, deptRecharge.getVersion())
+                    .set(SysDeptRecharge::getVersion, deptRecharge.getVersion() + 1)
+                    .set(SysDeptRecharge::getBalance, currentBalance)
+                    .set(SysDeptRecharge::getScore, currentScore)
+                    .set(SysDeptRecharge::getUpdateTime, LocalDateTime.now())
+                    .set(SysDeptRecharge::getUpdateUser, operator));
+            if (!update) {
+                throw new RuntimeException("更新失败");
+            }
+        }
+
+        // 新增充值记录
+        SysDeptRechargeRecord rechargeRecord = new SysDeptRechargeRecord();
+        rechargeRecord.setRechargeId(deptRecharge.getId());
+        rechargeRecord.setChangeScore(toRecharge.getRechargeScore());
+        rechargeRecord.setChangeAmount(toRecharge.getRechargeAmount());
+        rechargeRecord.setCurrentBalance(currentBalance);
+        rechargeRecord.setCurrentScore(currentScore);
+        rechargeRecord.setType(RechargeRecordType.RECHARGE);
+        rechargeRecord.setDeptId(deptRecharge.getDeptId());
+        rechargeRecord.setRelationDeptId(deptId);
+        rechargeRecord.setCreateUser(operator);
+        deptRechargeRecordService.save(rechargeRecord);
+
+        return Boolean.TRUE;
+    }
+
+    /**
+     * 配置(权限管理)
+     *
+     * @param toConfig 配置参数
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean toConfig(SysDeptRechargeRequest.ToConfig toConfig) {
+        Integer operator = SecurityUtils.getUser().getId();
+        // 更新配置数据
+        SysDeptRecharge deptRecharge = this.getOne(Wrappers.<SysDeptRecharge>lambdaQuery()
+                .eq(SysDeptRecharge::getDeptId, toConfig.getDeptId())
+                .eq(SysDeptRecharge::getDelFlag, DelEnum.NOT_DEL.val()));
+        // 透支金额 = 透支积分 * (服务费率/100)
+        BigDecimal overdrawAmount = null;
+        if (toConfig.getOverdrawScore() != null && toConfig.getOverdrawScore() > 0) {
+            overdrawAmount = BigDecimal.valueOf(toConfig.getOverdrawScore()).multiply(toConfig.getServiceCharge().divide(new BigDecimal("100.00")))
+                    .setScale(2, RoundingMode.HALF_EVEN);
+        } else {
+            overdrawAmount = BigDecimal.ZERO;
+            toConfig.setOverdrawScore(0);
+        }
+
+        if (deptRecharge == null) {
+            // 不存在则新增一条
+            deptRecharge = new SysDeptRecharge();
+            deptRecharge.setDeptId(toConfig.getDeptId());
+            deptRecharge.setServiceCharge(toConfig.getServiceCharge());
+            deptRecharge.setOverdrawScore(toConfig.getOverdrawScore());
+            deptRecharge.setOverdrawAmount(overdrawAmount);
+            deptRecharge.setPermissions(toConfig.getPermissions());
+            deptRecharge.setScore(0);
+            deptRecharge.setBalance(BigDecimal.ZERO);
+            deptRecharge.setCreateUser(operator);
+            this.save(deptRecharge);
+        } else {
+            // 更新
+            boolean update = this.update(Wrappers.<SysDeptRecharge>lambdaUpdate()
+                    .eq(SysDeptRecharge::getId, deptRecharge.getId())
+                    .eq(SysDeptRecharge::getVersion, deptRecharge.getVersion())
+                    .set(SysDeptRecharge::getVersion, deptRecharge.getVersion() + 1)
+                    .set(SysDeptRecharge::getServiceCharge, toConfig.getServiceCharge())
+                    .set(SysDeptRecharge::getOverdrawScore, toConfig.getOverdrawScore())
+                    .set(SysDeptRecharge::getOverdrawAmount, overdrawAmount)
+                    .set(SysDeptRecharge::getPermissions, toConfig.getPermissions())
+                    .set(SysDeptRecharge::getUpdateTime, LocalDateTime.now())
+                    .set(SysDeptRecharge::getUpdateUser, operator));
+            if (!update) {
+                throw new RuntimeException("更新失败");
+            }
+        }
+
+        return Boolean.TRUE;
+    }
+}
+
+
+
+

+ 98 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptInvoiceRelationVO.java

@@ -0,0 +1,98 @@
+package com.qunzhixinxi.hnqz.admin.recharge.vo;
+
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceStatus;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 企业开票关联积分包VO
+ *
+ * @author snows
+ * @date 2023/6/16 15:35
+ */
+@Data
+public class SysDeptInvoiceRelationVO implements Serializable {
+    private static final long serialVersionUID = -3333768260717968665L;
+
+    /**
+     * 积分包id
+     */
+    private String scorePackageId;
+
+    /**
+     * 积分包名称
+     */
+    private String scorePackageName;
+
+    /**
+     * 发包企业id
+     */
+    private Integer deptId;
+
+    /**
+     * 发包企业
+     */
+    private String deptName;
+
+    /**
+     * 积分包值
+     */
+    private Integer score;
+
+    /**
+     * 发布日期
+     */
+    private LocalDateTime packageCreateTime;
+
+    /**
+     * 接单对象
+     */
+    private String taskUsers;
+
+    /**
+     * 积分包状态
+     */
+    private String scorePackageStatus;
+
+    /**
+     * 积分包状态名称
+     */
+    private String scorePackageStatusStr;
+
+    /**
+     * 申请时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 企业开票表ID
+     */
+    private Integer invoiceId;
+
+    /**
+     * 开票状态
+     */
+    private InvoiceStatus invoiceStatus = InvoiceStatus.NOT_APPLY;
+
+    /**
+     * 开票状态名称
+     */
+    private String invoiceStatusStr = InvoiceStatus.NOT_APPLY.getDescription();
+
+    /**
+     * 开票时间
+     */
+    private LocalDateTime invoiceTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private Integer updateUser;
+}

+ 113 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptInvoiceVO.java

@@ -0,0 +1,113 @@
+package com.qunzhixinxi.hnqz.admin.recharge.vo;
+
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceApprovalStatus;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.InvoiceType;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 企业开票表
+ * @TableName sys_dept_invoice
+ */
+@Data
+public class SysDeptInvoiceVO implements Serializable {
+    private static final long serialVersionUID = 7897443620044727943L;
+
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 企业名称
+     */
+    private String deptName;
+
+    /**
+     * 开票金额(元)
+     */
+    private BigDecimal invoiceAmount;
+
+    /**
+     * 关联积分值
+     */
+    private Integer relationPackageScore;
+
+    /**
+     * 关联积分包个数
+     */
+    private Integer relationPackageNumber;
+
+    /**
+     * 审核状态
+     */
+    private InvoiceApprovalStatus approvalStatus;
+
+    /**
+     * 审核状态名称
+     */
+    private String approvalStatusStr;
+
+    /**
+     * 审核时间
+     */
+    private LocalDateTime approvalTime;
+
+    /**
+     * 发票类型
+     */
+    private InvoiceType invoiceType;
+
+    /**
+     * 发票类型名称
+     */
+    private String invoiceTypeStr;
+
+    /**
+     * 邮寄地址
+     */
+    private String address;
+
+    /**
+     * 收件人姓名
+     */
+    private String addresseeName;
+
+    /**
+     * 收件人手机号
+     */
+    private String addresseePhone;
+
+    /**
+     * 是否删除
+     */
+    private String delFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private Integer updateUser;
+}

+ 69 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeForParkVO.java

@@ -0,0 +1,69 @@
+package com.qunzhixinxi.hnqz.admin.recharge.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 积分充值表VO
+ */
+@Data
+public class SysDeptRechargeForParkVO implements Serializable {
+    private static final long serialVersionUID = -7923044280968088176L;
+
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 企业名称
+     */
+    private String deptName;
+
+    /**
+     * 企业类型
+     */
+    private Integer deptLevel;
+
+    /**
+     * 企业类型名称
+     */
+    private String deptLevelStr;
+
+    /**
+     * 积分余额
+     */
+    private Integer score = 0;
+
+    /**
+     * 可分配积分
+     */
+    private Integer distributableScore = 0;
+
+    /**
+     * 本月已分配积分
+     */
+    private Integer monthDistributeScore = 0;
+
+    /**
+     * 本月消耗积分
+     */
+    private Integer monthUsedScore = 0;
+
+    /**
+     * 可开票积分
+     */
+    private Integer toInvoiceScore = 0;
+
+    /**
+     * 本月开票积分
+     */
+    private Integer monthInvoiceScore = 0;
+
+}

+ 89 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeRecordForDeptVO.java

@@ -0,0 +1,89 @@
+package com.qunzhixinxi.hnqz.admin.recharge.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 积分充值/使用记录表VO
+ */
+@Data
+public class SysDeptRechargeRecordForDeptVO implements Serializable {
+    private static final long serialVersionUID = -757283078695677161L;
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 积分充值表ID
+     */
+    private Integer rechargeId;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 企业名称
+     */
+    private String deptName;
+
+    /**
+     * 企业类型
+     */
+    private Integer deptLevel;
+
+    /**
+     * 企业类型名称
+     */
+    private String deptLevelStr;
+
+    /**
+     * 充值/消耗积分
+     */
+    private Integer changeScore;
+
+    /**
+     * 操作类型
+     */
+    private RechargeRecordType type;
+
+    /**
+     * 充值/消耗后积分余额
+     */
+    private Integer currentScore;
+
+    /**
+     * 关联对象(相对于当前登录企业的另一方)
+     */
+    private String operatingTarget;
+
+    /**
+     * 积分包名称
+     */
+    private String scorePackageName;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+    /**
+     * 创建人名称
+     */
+    private String creaUserStr;
+
+}

+ 95 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeRecordVO.java

@@ -0,0 +1,95 @@
+package com.qunzhixinxi.hnqz.admin.recharge.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.qunzhixinxi.hnqz.admin.recharge.enums.RechargeRecordType;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 积分充值/使用记录表VO
+ */
+@Data
+public class SysDeptRechargeRecordVO implements Serializable {
+    private static final long serialVersionUID = -7467561813221224627L;
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 积分充值表ID
+     */
+    private Integer rechargeId;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 企业名称
+     */
+    private String deptName;
+
+    /**
+     * 企业类型
+     */
+    private Integer deptLevel;
+
+    /**
+     * 企业类型名称
+     */
+    private String deptLevelStr;
+
+    /**
+     * 充值/消耗积分
+     */
+    private Integer changeScore;
+
+    /**
+     * 充值金额(元)
+     */
+    private BigDecimal changeAmount;
+
+    /**
+     * 操作类型
+     */
+    private RechargeRecordType type;
+
+    /**
+     * 充值/消耗后积分余额
+     */
+    private Integer currentScore;
+
+    /**
+     * 充值后积分余额(元)
+     */
+    private BigDecimal currentBalance;
+
+    /**
+     * 是否删除
+     */
+    private String delFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建人
+     */
+    private Integer createUser;
+
+    /**
+     * 创建人名称
+     */
+    private String creaUserStr;
+
+}

+ 85 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/recharge/vo/SysDeptRechargeVO.java

@@ -0,0 +1,85 @@
+package com.qunzhixinxi.hnqz.admin.recharge.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 积分充值表VO
+ */
+@Data
+public class SysDeptRechargeVO implements Serializable {
+    private static final long serialVersionUID = -7923044280968088176L;
+
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 组织机构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 企业名称
+     */
+    private String deptName;
+
+    /**
+     * 企业类型
+     */
+    private Integer deptLevel;
+
+    /**
+     * 企业类型名称
+     */
+    private String deptLevelStr;
+
+    /**
+     * 积分余额
+     */
+    private Integer score = 0;
+
+    /**
+     * 余额(元)
+     */
+    private BigDecimal balance = BigDecimal.ZERO;
+
+    /**
+     * 权限
+     */
+    private String[] permissions;
+
+    /**
+     * 服务费率
+     */
+    private BigDecimal serviceCharge;
+
+    /**
+     * 可透支金额
+     */
+    private BigDecimal overdrawAmount;
+
+    /**
+     * 可透支积分
+     */
+    private Integer overdrawScore;
+
+    /**
+     * 累计充值积分
+     */
+    private Integer totalRechargeScore = 0;
+
+    /**
+     * 累计开票积分
+     */
+    private Integer totalInvoiceScore = 0;
+
+    /**
+     * 累计开票金额(元)
+     */
+    private BigDecimal totalInvoiceAmount = BigDecimal.ZERO;
+
+}

+ 80 - 0
hnqz-upms/hnqz-upms-biz/src/main/resources/mapper/SysDeptInvoiceRelationMapper.xml

@@ -0,0 +1,80 @@
+<?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.qunzhixinxi.hnqz.admin.recharge.mapper.SysDeptInvoiceRelationMapper">
+
+    <resultMap id="BaseResultMap" type="com.qunzhixinxi.hnqz.admin.recharge.entity.SysDeptInvoiceRelation">
+            <id property="id" column="id" jdbcType="INTEGER"/>
+            <result property="invoiceId" column="invoice_id" jdbcType="INTEGER"/>
+            <result property="deptId" column="dept_id" jdbcType="INTEGER"/>
+            <result property="packageId" column="package_id" jdbcType="INTEGER"/>
+            <result property="invoiceStatus" column="invoice_status" jdbcType="VARCHAR"/>
+            <result property="invoiceTime" column="invoice_time" jdbcType="TIMESTAMP"/>
+            <result property="delFlag" column="del_flag" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="createUser" column="create_user" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <select id="pageInvoiceScorePacakgeRelation"
+            resultType="com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO">
+        SELECT p.id, p.id as score_package_id, p.score_package_name, p.score, p.score_package_status, p.send_package_dept_id as dept_id, p.create_time as package_create_time,
+             r.invoice_id, r.invoice_status, r.invoice_time, r.create_time, r.create_user, r.update_time, r.update_user
+        FROM wm_score_package p
+        LEFT JOIN sys_dept_invoice_relation r on r.package_id = p.id AND r.del_flag = '0'
+        <where>
+            AND p.package_type1 = '1' AND p.package_type2 = '1' AND p.score_package_status = '4' AND p.typeid = '4'
+            AND p.send_package_dept_id IN
+            <foreach collection="deptIdList" item="deptId" index="idx" separator="," open="(" close=")">
+                #{deptId}
+            </foreach>
+            <if test="query.invoiceStatus != null and query.invoiceStatus.status == 'NOT_APPLY'">
+                AND (r.invoice_status is null OR r.invoice_status = 'NOT_APPLY')
+            </if>
+            <if test="query.invoiceStatus != null and query.invoiceStatus.status != 'NOT_APPLY'">
+                AND r.invoice_status = #{query.invoiceStatus.status}
+            </if>
+            <if test="query.createTime != null and query.createTime.length == 2">
+                AND r.create_time between #{query.createTime[0]} and #{query.createTime[1]}
+            </if>
+        </where>
+    </select>
+
+    <select id="listInvoiceScorePacakgeRelation"
+            resultType="com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO">
+        SELECT p.id, p.id as score_package_id, p.score_package_name, p.score, p.score_package_status, p.send_package_dept_id as dept_id, p.create_time as package_create_time,
+        r.invoice_id, r.invoice_status, r.invoice_time, r.create_time, r.create_user, r.update_time, r.update_user
+        FROM wm_score_package p
+        LEFT JOIN sys_dept_invoice_relation r on r.package_id = p.id AND r.del_flag = '0'
+        <where>
+            AND p.package_type1 = '1' AND p.package_type2 = '1' AND p.score_package_status = '4' AND p.typeid = '4'
+            AND p.send_package_dept_id IN
+            <foreach collection="deptIdList" item="deptId" index="idx" separator="," open="(" close=")">
+                #{deptId}
+            </foreach>
+            <if test="query.invoiceStatus != null and query.invoiceStatus.status == 'NOT_APPLY'">
+                AND (r.invoice_status is null OR r.invoice_status = 'NOT_APPLY')
+            </if>
+            <if test="query.invoiceStatus != null and query.invoiceStatus.status != 'NOT_APPLY'">
+                AND r.invoice_status = #{query.invoiceStatus.status}
+            </if>
+            <if test="query.createTime != null and query.createTime.length == 2">
+                AND r.create_time between #{query.createTime[0]} and #{query.createTime[1]}
+            </if>
+        </where>
+    </select>
+
+    <select id="pageInvoiceScorePacakgeRelation2"
+            resultType="com.qunzhixinxi.hnqz.admin.recharge.vo.SysDeptInvoiceRelationVO">
+        SELECT p.id, p.id as score_package_id, p.score_package_name, p.score, p.score_package_status, p.send_package_dept_id as dept_id, p.create_time as package_create_time,
+        r.invoice_id, r.invoice_status, r.invoice_time, r.create_time, r.create_user, r.update_time, r.update_user
+        FROM wm_score_package p
+        LEFT JOIN sys_dept_invoice_relation r on r.package_id = p.id
+        <where>
+            AND p.package_type1 = '1' AND p.package_type2 = '1' AND p.score_package_status = '4' AND p.typeid = '4'
+            AND r.del_flag = '0'
+            AND r.invoice_id = #{invoiceId}
+        </where>
+    </select>
+
+</mapper>