feat:图片审核盖章

This commit is contained in:
dzc committed 2025-07-04 11:51:52 +08:00
1 parent 45aa0598f2
commit 65097f7bd7
8 files changed
+133 -8

No files matched your search

@@ -28,4 +28,13 @@ public class WalletRechargeBindInvoiceDto extends WalletRechargeInvoiceVo {
*/ */
private LocalDateTime[] createTimeList; private LocalDateTime[] createTimeList;
/**
* 申请时间
*/
private LocalDateTime[] applyTimeList;
/**
* 审核时间
*/
private LocalDateTime[] processTimeList;
} }
@@ -107,6 +107,12 @@ public class WalletRechargeInvoiceEntity extends Model<WalletRechargeInvoiceEnti
@Schema(description = "发票图片地址(不盖章)") @Schema(description = "发票图片地址(不盖章)")
private String picUrl; private String picUrl;
/**
* 发票图片地址(盖章)
*/
@Schema(description = "发票图片地址(盖章)")
private String stampPicUrl;
/** /**
* 流程id * 流程id
*/ */
@@ -71,7 +71,7 @@ public interface WalletRechargeInvoiceService extends IService<WalletRechargeInv
void apply(@Valid WalletRechargeInvoiceApplyDto body); void apply(@Valid WalletRechargeInvoiceApplyDto body);
/** /**
* 盖章 * 生成盖章图片
*/ */
void stamp(WalletRechargeInvoiceEntity invoice); String stamp(WalletRechargeInvoiceEntity invoice);
} }
@@ -3,6 +3,7 @@ package com.bsd.pjcloud.wallet.service.impl.recharge;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
@@ -13,8 +14,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.admin.api.dto.UserInfo; import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.entity.SysDept; import com.bsd.pjcloud.admin.api.entity.SysDept;
import com.bsd.pjcloud.admin.api.feign.RemoteDeptService; import com.bsd.pjcloud.admin.api.feign.RemoteDeptService;
import com.bsd.pjcloud.admin.api.feign.RemoteFileService;
import com.bsd.pjcloud.admin.api.feign.RemoteUserService; import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.resolver.ParamResolver;
import com.bsd.pjcloud.common.data.tenant.TenantContextHolder; import com.bsd.pjcloud.common.data.tenant.TenantContextHolder;
import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum; import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
@@ -37,16 +41,27 @@ import com.bsd.pjcloud.wallet.service.WalletRechargeInvoiceService;
import com.bsd.pjcloud.wallet.utils.ConvertCnPriceUtil; import com.bsd.pjcloud.wallet.utils.ConvertCnPriceUtil;
import com.bsd.pjcloud.wallet.utils.flow.FlowUtil; import com.bsd.pjcloud.wallet.utils.flow.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.dto.WalletRechargeInvoiceFlowDto; import com.bsd.pjcloud.wallet.utils.flow.dto.WalletRechargeInvoiceFlowDto;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.transaction.annotation.Transactional;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.net.URL;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 充值/扣款申请发票记录 * 充值/扣款申请发票记录
@@ -65,7 +80,7 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
private final RemoteUserService remoteUserService; private final RemoteUserService remoteUserService;
private final RemoteDeptService remoteDeptService; private final RemoteDeptService remoteDeptService;
private final RemoteFileService remoteFileService;
private final RemoteWalletSettingService remoteWalletSettingService; private final RemoteWalletSettingService remoteWalletSettingService;
/** /**
@@ -285,7 +300,11 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
if (isConsent) { if (isConsent) {
// 盖章 // 盖章
String stampPicUrl = stamp(detail);
if (ObjectUtil.isNotEmpty(stampPicUrl)) {
// 更新盖章图片
baseMapper.updateById(WalletRechargeInvoiceEntity.builder().id(detail.getId()).stampPicUrl(stampPicUrl).build());
}
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -334,11 +353,57 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
} }
/** /**
* 盖章 * 生成盖章图片
*/ */
@Override @Override
public void stamp(WalletRechargeInvoiceEntity invoice) { public String stamp(WalletRechargeInvoiceEntity invoice) {
// 查看有没有盖章
if (ObjectUtil.isEmpty(invoice)) {
log.error("|{}|盖章失败,发票查询为空,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice));
return null;
}
// 审核成功才能开发票
if (ObjectUtil.notEqual(invoice.getProcessStatus(), TaskCheckStatusEnum.RESULT.getCode()) && false) {
log.error("|{}|盖章失败,审核成功才能开发票,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice));
return null;
}
String imageBaseUrl = ParamResolver.getStr("IMAGE_BASE_URL");
if (ObjectUtil.isEmpty(imageBaseUrl)) {
throw new RuntimeException("请配置图片基础路径");
}
// 开始盖章
String picUrl = String.format("%s%s", imageBaseUrl, invoice.getPicUrl());
File receiptStamp = FileUtil.file("image/receiptStamp.png");
// 发票底图宽高 6615 x 3591
int baseMapWidth = 6615, baseMapHeight = 3591;
// 盖章图片宽高
int stampWidth = 1000, stampHeight = 1000;
try {
// 读取底图
BufferedImage baseImage = ImageIO.read(new URL(picUrl));
// 读取盖章图片
BufferedImage stampImage = ImageIO.read(receiptStamp);
// 创建新的图像上下文
Graphics2D g2d = baseImage.createGraphics();
// 设置抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int x = (int) (stampWidth + baseMapWidth * 0.15 - 50);
int y = baseMapHeight - stampHeight - 100;
g2d.drawImage(stampImage, x, y, stampWidth, stampHeight, null);
g2d.dispose();
String newPicUrl = invoice.getPicUrl().replaceFirst("(\\.\\w+)$", "_stamped$1");
File tempFile = File.createTempFile(newPicUrl, ".png");
ImageIO.write(baseImage, "PNG", tempFile);
// 上传图片
MultipartFile multipartFile = new MockMultipartFile("file", newPicUrl, "image/png", new FileInputStream(tempFile));
R upload = remoteFileService.innerUpload(multipartFile, null, null, null);
Map data = (Map) upload.getData();
String url = (String) data.get("url");
return url;
} catch (IOException e) {
log.error("|{}|盖章失败,IO异常,invoice:|{}|error:|{}|", TAG, JSONUtil.toJsonStr(invoice), e.getMessage());
return null;
}
} }
/** /**
Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

@@ -17,6 +17,11 @@
a.remark, a.remark,
a.status, a.status,
a.pic_url, a.pic_url,
a.stamp_pic_url,
a.process_id,
a.process_status,
a.apply_time,
a.process_time,
a.create_by, a.create_by,
a.create_time, a.create_time,
a.update_by, a.update_by,
@@ -30,6 +35,9 @@
<if test="dto.status != null"> <if test="dto.status != null">
and a.status = #{dto.status} and a.status = #{dto.status}
</if> </if>
<if test="dto.processStatus != null">
and a.process_status = #{dto.processStatus}
</if>
<if test="dto.userIds != null and dto.userIds.size() != 0"> <if test="dto.userIds != null and dto.userIds.size() != 0">
and a.apply_user_id in and a.apply_user_id in
<foreach collection="dto.userIds" item="v" open="(" close=")" separator=","> <foreach collection="dto.userIds" item="v" open="(" close=")" separator=",">
@@ -39,6 +47,12 @@
<if test="dto.createTimeList != null and dto.createTimeList.length == 2"> <if test="dto.createTimeList != null and dto.createTimeList.length == 2">
and a.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]} and a.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]}
</if> </if>
<if test="dto.applyTimeList != null and dto.applyTimeList.length == 2">
and a.apply_time between #{dto.applyTimeList[0]} and #{dto.applyTimeList[1]}
</if>
<if test="dto.processTimeList != null and dto.processTimeList.length == 2">
and a.process_time between #{dto.processTimeList[0]} and #{dto.processTimeList[1]}
</if>
</sql> </sql>
<select id="selectAllCount" resultType="java.lang.Long"> <select id="selectAllCount" resultType="java.lang.Long">
@@ -0,0 +1,31 @@
package com.bsd.pjcloud;
import cn.hutool.core.util.ObjectUtil;
import com.bsd.pjcloud.wallet.WalletApp;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeInvoiceEntity;
import com.bsd.pjcloud.wallet.service.WalletRechargeInvoiceService;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
/**
* @author liusiyang_dxm
* @since 2025/7/4
*/
@SpringBootTest(classes = WalletApp.class)
public class InvoiceTest {
@Resource
private WalletRechargeInvoiceService invoiceService;
@Test
@Transactional
public void test() {
WalletRechargeInvoiceEntity detail = invoiceService.getById(1937849346822692865L);
if (ObjectUtil.isNotEmpty(detail)) {
invoiceService.stamp(detail);
}
}
}