Bladeren bron

志愿者APP提现与后台提现管理

wangwl 3 dagen geleden
bovenliggende
commit
affed1f031
29 gewijzigde bestanden met toevoegingen van 2193 en 13 verwijderingen
  1. 13 2
      leromro-admin/src/main/resources/application.yml
  2. 6 0
      leromro-common/pom.xml
  3. 263 0
      leromro-common/src/main/java/com/leromro/common/utils/MyImgUtil.java
  4. 3 2
      leromro-core/src/main/java/com/leromro/core/controller/SmsController.java
  5. 40 5
      leromro-core/src/main/java/com/leromro/core/controller/VolunteerAccountController.java
  6. 106 0
      leromro-core/src/main/java/com/leromro/core/controller/VolunteerPaymentRecordsController.java
  7. 88 0
      leromro-core/src/main/java/com/leromro/core/controller/VolunteerTakeRecordController.java
  8. 90 0
      leromro-core/src/main/java/com/leromro/core/domain/VolunteerPaymentRecords.java
  9. 160 0
      leromro-core/src/main/java/com/leromro/core/domain/VolunteerTakeRecord.java
  10. 16 0
      leromro-core/src/main/java/com/leromro/core/domain/dto/AddPaymentRecordDTO.java
  11. 56 0
      leromro-core/src/main/java/com/leromro/core/domain/dto/VolunteerSubmitAmountDTO.java
  12. 56 0
      leromro-core/src/main/java/com/leromro/core/domain/dto/WithdrawPaymentDTO.java
  13. 29 0
      leromro-core/src/main/java/com/leromro/core/domain/vo/AlipayCashWithdrawal.java
  14. 9 2
      leromro-core/src/main/java/com/leromro/core/domain/vo/VolunteerAccountChangeVO.java
  15. 90 0
      leromro-core/src/main/java/com/leromro/core/facade/VolunteerAccountFacade.java
  16. 65 0
      leromro-core/src/main/java/com/leromro/core/facade/VolunteerPaymentRecordsFacade.java
  17. 62 0
      leromro-core/src/main/java/com/leromro/core/mapper/VolunteerPaymentRecordsMapper.java
  18. 62 0
      leromro-core/src/main/java/com/leromro/core/mapper/VolunteerTakeRecordMapper.java
  19. 71 0
      leromro-core/src/main/java/com/leromro/core/service/IVolunteerPaymentRecordsService.java
  20. 62 0
      leromro-core/src/main/java/com/leromro/core/service/IVolunteerTakeRecordService.java
  21. 295 0
      leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerPaymentRecordsServiceImpl.java
  22. 96 0
      leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerTakeRecordServiceImpl.java
  23. 8 1
      leromro-core/src/main/resources/mapper/core/VolunteerAccountChangeMapper.xml
  24. 134 0
      leromro-core/src/main/resources/mapper/core/VolunteerPaymentRecordsMapper.xml
  25. 220 0
      leromro-core/src/main/resources/mapper/core/VolunteerTakeRecordMapper.xml
  26. 63 0
      leromro-framework/src/main/java/com/leromro/framework/config/AliConfig.java
  27. 3 1
      leromro-framework/src/main/java/com/leromro/framework/config/ConstantsConfig.java
  28. 20 0
      leromro-framework/src/main/java/com/leromro/framework/config/properties/AliAdminPayProperties.java
  29. 7 0
      pom.xml

File diff suppressed because it is too large
+ 13 - 2
leromro-admin/src/main/resources/application.yml


+ 6 - 0
leromro-common/pom.xml

@@ -183,6 +183,12 @@
             <artifactId>weixin-java-pay</artifactId>
         </dependency>
 
+        <!-- 支付宝支付 -->
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <artifactId>jackson-datatype-jdk8</artifactId>

+ 263 - 0
leromro-common/src/main/java/com/leromro/common/utils/MyImgUtil.java

@@ -0,0 +1,263 @@
+package com.leromro.common.utils;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+import javax.swing.ImageIcon;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MyImgUtil {
+    private static final Logger log = LoggerFactory.getLogger(MyImgUtil.class);
+
+    public static void cutImage(String srcFile, String targetFile, int startAcross, int StartEndlong, int width, int hight) throws Exception {
+        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
+        ImageReader reader = readers.next();
+        InputStream source = new FileInputStream(srcFile);
+        ImageInputStream iis = ImageIO.createImageInputStream(source);
+        reader.setInput(iis, true);
+        ImageReadParam param = reader.getDefaultReadParam();
+        Rectangle rect = new Rectangle(startAcross, StartEndlong, width, hight);
+        param.setSourceRegion(rect);
+        BufferedImage bi = reader.read(0, param);
+        ImageIO.write(bi, targetFile.split("\\.")[1], new File(targetFile));
+    }
+
+
+    public static final void overlapImage(String bigPath, String smallPath, String outFile, int x, int y, int width, int height) {
+        try {
+            BufferedImage big = ImageIO.read(new File(bigPath));
+            BufferedImage small = ImageIO.read(new File(smallPath));
+            Graphics2D g = big.createGraphics();
+            g.drawImage(small, x, y, width, height, (ImageObserver) null);
+            g.dispose();
+            ImageIO.write(big, outFile.split("\\.")[1], new File(outFile));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static final byte[] overlapImage(byte[] bigImgByte, byte[] smallImgByte, int x, int y, int width, int height) {
+        try {
+            InputStream bigIn = new ByteArrayInputStream(bigImgByte);
+            BufferedImage big = ImageIO.read(bigIn);
+            InputStream in = new ByteArrayInputStream(smallImgByte);
+            BufferedImage small = ImageIO.read(in);
+            Graphics2D g = big.createGraphics();
+            g.drawImage(small, x, y, width, height, (ImageObserver) null);
+            g.dispose();
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ImageIO.write(big, "png", baos);
+            baos.flush();
+            byte[] imageInByte = baos.toByteArray();
+            baos.close();
+            return imageInByte;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void drawStringForImage(String filePath, String content, Color contentColor, float qualNum, String targetFile, int x, int y) {
+        ImageIcon imgIcon = new ImageIcon(filePath);
+        Image theImg = imgIcon.getImage();
+        int width = theImg.getWidth((ImageObserver) null) == -1 ? 200 : theImg.getWidth((ImageObserver) null);
+        int height = theImg.getHeight((ImageObserver) null) == -1 ? 200 : theImg.getHeight((ImageObserver) null);
+        BufferedImage bimage = new BufferedImage(width, height, 1);
+        Graphics2D g = bimage.createGraphics();
+        g.setColor(contentColor);
+        g.setBackground(Color.red);
+        g.drawImage(theImg, 0, 0, (ImageObserver) null);
+        g.setFont(new Font("微软雅黑", 1, 30));
+        g.drawString(content, x, y);
+        g.dispose();
+        FileOutputStream out = null;
+        try {
+            try {
+                String formatName = targetFile.substring(targetFile.lastIndexOf(".") + 1);
+                ImageIO.write(bimage, formatName, new File(targetFile));
+                if (0 != 0) {
+                    try {
+                        out.close();
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            } catch (Throwable th) {
+                if (0 != 0) {
+                    try {
+                        out.close();
+                    } catch (IOException e2) {
+                        throw new RuntimeException(e2);
+                    }
+                }
+                throw th;
+            }
+        } catch (Exception e3) {
+            throw new RuntimeException(e3);
+        }
+    }
+
+    public static byte[] getImageFromNetByUrl(String strUrl) {
+        try {
+            URL url = new URL(strUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("GET");
+            conn.setConnectTimeout(5000);
+            InputStream inStream = conn.getInputStream();
+            byte[] btImg = readInputStream(inStream);
+            return btImg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] readInputStream(InputStream inStream) throws Exception {
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        byte[] buffer = new byte[6024];
+        while (true) {
+            int len = inStream.read(buffer);
+            if (len != -1) {
+                outStream.write(buffer, 0, len);
+            } else {
+                inStream.close();
+                return outStream.toByteArray();
+            }
+        }
+    }
+
+    public static void buff2Image(byte[] b, String filePath) throws Exception {
+        FileOutputStream fout = new FileOutputStream(filePath);
+        fout.write(b);
+        fout.close();
+    }
+
+    public static void deleteImg(String filePath) throws Exception {
+        File file = new File(filePath);
+        file.delete();
+    }
+
+
+
+    public static byte[] createPromoteQrcode(byte[] bigImgByte, byte[] smallImgByte, int x, int y, int width, int height) throws Exception {
+        try {
+            System.out.println("开始生成推广图片-----------");
+            byte[] result = overlapImage(bigImgByte, smallImgByte, x, y, width, height);
+            System.out.println("结束生成推广图片-----------");
+            return result;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] modifyImgSizeByUrl(String url, int with, int height) {
+        try {
+            log.info("url:" + url);
+            URL img = new URL(url);
+            log.info("img:" + img);
+            BufferedImage image = ImageIO.read(img);
+            BufferedImage newImage = resizeImage(image, with, height);
+            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+            ImageIO.write(newImage, "PNG", outStream);
+            return outStream.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] modifyImg(String url, int radius) {
+        try {
+            log.info("url:" + url);
+            URL img = new URL(url);
+            log.info("img:" + img);
+            BufferedImage image = ImageIO.read(img);
+            BufferedImage newImage = setClip(image, radius);
+            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+            ImageIO.write(newImage, "PNG", outStream);
+            return outStream.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] modifyImgSizeByByte(byte[] myByte, int with, int height) {
+        try {
+            ByteArrayInputStream in = new ByteArrayInputStream(myByte);
+            BufferedImage image = ImageIO.read(in);
+            BufferedImage newImage = resizeImage(image, with, height);
+            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+            ImageIO.write(newImage, "PNG", outStream);
+            return outStream.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
+        Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, 16);
+        BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, 1);
+        outputImage.getGraphics().drawImage(resultingImage, 0, 0, (ImageObserver) null);
+        return outputImage;
+    }
+
+    public static BufferedImage setClip(BufferedImage srcImage, int radius) {
+        int width = srcImage.getWidth();
+        int height = srcImage.getHeight();
+        BufferedImage image = new BufferedImage(width, height, 2);
+        Graphics2D gs = image.createGraphics();
+        gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        gs.setClip(new RoundRectangle2D.Double(0.0d, 0.0d, width, height, radius, radius));
+        gs.drawImage(srcImage, 0, 0, (ImageObserver) null);
+        gs.dispose();
+        return image;
+    }
+
+    public static byte[] imageToBytes(BufferedImage bImage) {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            ImageIO.write(bImage, "png", out);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return out.toByteArray();
+    }
+
+    private static BufferedImage bytesToBufferedImage(byte[] ImageByte) {
+        ByteArrayInputStream in = new ByteArrayInputStream(ImageByte);
+        BufferedImage image = null;
+        try {
+            image = ImageIO.read(in);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return image;
+    }
+
+
+
+}

+ 3 - 2
leromro-core/src/main/java/com/leromro/core/controller/SmsController.java

@@ -38,14 +38,14 @@ public class SmsController {
     public AjaxResult sendCode(@PathVariable(name = "phone")String phone) {
         //校验是否才发过验证码
         if (ObjectUtil.isNotNull(redisCache.getCacheObject(ConstantsKey.REDIS_PHONE_CODE.getKey() + "_" + phone + "_interval"))) {
-            return AjaxResult.error(-1, "验证码已发送,请稍后再试");
+            return AjaxResult.error( "验证码已发送,请稍后再试");
         }
         String code = (Math.random() + "").substring(2, 6);
         JSONObject jsonObject = new JSONObject();
         jsonObject.putOnce("code", code);
         String send = SendSmsUtil.send(phone, jsonObject.toString(), ConstantsConfig.SMS_TEMPLATE_TYPE_PHONE_CODE.getValue());
         if (StrUtil.isBlank(send)) {
-            return AjaxResult.error(-1, "验证码发送失败");
+            return AjaxResult.error( "验证码发送失败");
         }
         //设置值
         redisCache.setCacheObject(ConstantsKey.REDIS_PHONE_CODE.getKey() + "_" + phone, code, Integer.parseInt(ConstantsConfig.REDIS_SHORT_TIMELONG.getValue()), TimeUnit.SECONDS);
@@ -59,6 +59,7 @@ public class SmsController {
      * 校验验证码
      */
     @GetMapping({"/checkSmsCode/{phone}/{code}"})
+    @ApiOperation(value = "校验验证码", notes = "校验验证码")
     public AjaxResult checkSmsCode(@PathVariable(name = "phone")String phone,
                                    @PathVariable(name = "code")String code) {
         String redisCode = this.redisCache.getCacheObject(ConstantsKey.REDIS_PHONE_CODE.getKey() + "_" + phone);

+ 40 - 5
leromro-core/src/main/java/com/leromro/core/controller/VolunteerAccountController.java

@@ -3,12 +3,17 @@ package com.leromro.core.controller;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.leromro.core.domain.dto.VolunteerSubmitAmountDTO;
+import com.leromro.core.facade.VolunteerAccountFacade;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import com.leromro.common.core.domain.R;
+import org.apache.poi.ss.formula.functions.T;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
+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.PutMapping;
@@ -28,18 +33,20 @@ import com.leromro.common.core.page.TableDataInfo;
 
 /**
  * 志愿者账户Controller
- * 
+ *
  * @author ruoyi
  * @date 2025-04-11
  */
 @RestController
 @Api(tags = "志愿者账户")
 @RequestMapping("/core/volunteer/account")
-public class VolunteerAccountController extends BaseController
-{
+public class VolunteerAccountController extends BaseController {
     @Autowired
     private IVolunteerAccountService volunteerAccountService;
 
+    @Autowired
+    private VolunteerAccountFacade volunteerAccountFacade;
+
 //    /**
 //     * 查询志愿者账户列表
 //     */
@@ -58,12 +65,40 @@ public class VolunteerAccountController extends BaseController
      */
     @ApiOperation("获取志愿者账户详细信息")
     @GetMapping("/getVolunteerAccountInfo")
-    public R<VolunteerAccount> getVolunteerAccountInfo()
-    {
+    public R<VolunteerAccount> getVolunteerAccountInfo() {
         return R.ok(volunteerAccountService.getOne(new LambdaQueryWrapper<VolunteerAccount>()
                 .eq(VolunteerAccount::getVolunteerId, getUserId())));
     }
 
+    /**
+     * 提交提现申请
+     */
+    @PostMapping({"/submitAmountApply"})
+    @ApiOperation(value = "提交提现申请", notes = "提交提现申请", produces = "application/json")
+    public R submitAmountApply(@RequestBody @Validated VolunteerSubmitAmountDTO dto) {
+        if (dto.getPayType().equals("1")) {
+            return R.fail("暂不支持银行卡提现");
+        } else if (dto.getPayType().equals("2")) {
+            if (StrUtil.isBlank(dto.getAlipayAccountNo())) {
+                return R.fail("支付宝账户不能为空");
+            }
+            if (StrUtil.isBlank(dto.getAlipayAccountNo())) {
+                return R.fail("支付宝名称不能为空");
+            }
+        }
+        return volunteerAccountFacade.submitAmountApply(dto);
+    }
+
+    /**
+     * 获取当前用户提现状态
+     */
+    @GetMapping({"/getWithdrawStatus"})
+    @ApiOperation(value = "获取当前用户提现状态", notes = "返回200允许填写,返回500直接提示", produces = "application/json")
+    public R getWithdrawStatus() {
+        return volunteerAccountFacade.getWithdrawStatus();
+    }
+
+
 
 
 }

+ 106 - 0
leromro-core/src/main/java/com/leromro/core/controller/VolunteerPaymentRecordsController.java

@@ -0,0 +1,106 @@
+package com.leromro.core.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotBlank;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.leromro.common.core.domain.entity.SysUser;
+import com.leromro.core.domain.dto.AddPaymentRecordDTO;
+import com.leromro.core.domain.dto.WithdrawPaymentDTO;
+import com.leromro.core.facade.VolunteerPaymentRecordsFacade;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import com.leromro.common.core.domain.R;
+import org.hibernate.validator.constraints.Range;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.leromro.common.annotation.Log;
+import com.leromro.common.core.controller.BaseController;
+import com.leromro.common.core.domain.AjaxResult;
+import com.leromro.common.enums.BusinessType;
+import com.leromro.core.domain.VolunteerPaymentRecords;
+import com.leromro.core.service.IVolunteerPaymentRecordsService;
+import com.leromro.common.utils.poi.ExcelUtil;
+import com.leromro.common.core.page.TableDataInfo;
+
+/**
+ * 志愿者打款单记录Controller
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+@RestController
+@Api(tags = "志愿者打款单记录")
+@RequestMapping("/core/volunteer/payment")
+public class VolunteerPaymentRecordsController extends BaseController
+{
+    @Autowired
+    private IVolunteerPaymentRecordsService volunteerPaymentRecordsService;
+
+    @Autowired
+    private VolunteerPaymentRecordsFacade  volunteerPaymentRecordsFacade;
+
+
+    /**
+     * 创建志愿者打款单
+     */
+    @ApiOperation(value = "创建志愿者打款单",notes = "传入打款方式和选中的id名称逗号拼接")
+    @PostMapping
+    public R addPaymentRecord(@RequestBody AddPaymentRecordDTO dto)
+    {
+        return volunteerPaymentRecordsService.addPaymentRecord(dto);
+    }
+
+    /**
+     * 查询志愿者打款单记录列表
+     */
+    @ApiOperation("查询志愿者打款单记录列表")
+    @GetMapping("/list")
+    public TableDataInfo<VolunteerPaymentRecords> list(VolunteerPaymentRecords volunteerPaymentRecords)
+    {
+        startPage();
+        List<VolunteerPaymentRecords> list = volunteerPaymentRecordsService.selectVolunteerPaymentRecordsList(volunteerPaymentRecords);
+        return getDataTable(list);
+    }
+
+//    /**
+//     * 获取志愿者打款单记录详细信息
+//     */
+//    @ApiOperation("获取志愿者打款单记录详细信息")
+//    @GetMapping(value = "/{volunteerPaymentRecordsId}")
+//    public R<VolunteerPaymentRecords> getInfo(@PathVariable("volunteerPaymentRecordsId") Long volunteerPaymentRecordsId)
+//    {
+//        return R.ok(volunteerPaymentRecordsService.selectVolunteerPaymentRecordsByVolunteerPaymentRecordsId(volunteerPaymentRecordsId));
+//    }
+
+
+    /**
+     * 打款单验证
+     * @param dto
+     * @return
+     */
+    @PostMapping({"/payoutCheck"})
+    @ApiOperation(value = "打款单验证", notes = "传入打款单id,,和打款验证密码", produces = "application/json")
+    public R payoutCheck(@RequestBody WithdrawPaymentDTO dto) {
+        if (ObjectUtil.isNull(dto.getVolunteerPaymentRecordsId())) {
+            return R.fail(-1, "打款的记录表id不能为空");
+        }
+        if (StrUtil.isBlank(dto.getPayPassword())) {
+            return R.fail(-1, "打款验证密码不能为空");
+        }
+        return volunteerPaymentRecordsFacade.payoutCheck(dto);
+    }
+
+
+
+}

+ 88 - 0
leromro-core/src/main/java/com/leromro/core/controller/VolunteerTakeRecordController.java

@@ -0,0 +1,88 @@
+package com.leromro.core.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.leromro.common.utils.SecurityUtils;
+import com.leromro.core.domain.VolunteerInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import com.leromro.common.core.domain.R;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.leromro.common.annotation.Log;
+import com.leromro.common.core.controller.BaseController;
+import com.leromro.common.core.domain.AjaxResult;
+import com.leromro.common.enums.BusinessType;
+import com.leromro.core.domain.VolunteerTakeRecord;
+import com.leromro.core.service.IVolunteerTakeRecordService;
+import com.leromro.common.utils.poi.ExcelUtil;
+import com.leromro.common.core.page.TableDataInfo;
+
+/**
+ * 志愿者提现申请记录Controller
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+@RestController
+@Api(tags = "志愿者提现申请记录")
+@RequestMapping("/core/volunteer/take")
+public class VolunteerTakeRecordController extends BaseController
+{
+    @Autowired
+    private IVolunteerTakeRecordService volunteerTakeRecordService;
+
+    /**
+     * 查询志愿者提现申请记录列表
+     */
+    @ApiOperation(value = "查询志愿者提现申请记录列表",notes = "payType传2代表支付宝提现申请单")
+    @GetMapping("/list")
+    public TableDataInfo<VolunteerTakeRecord> list(VolunteerTakeRecord volunteerTakeRecord)
+    {
+        startPage();
+        List<VolunteerTakeRecord> list = volunteerTakeRecordService.selectVolunteerTakeRecordList(volunteerTakeRecord);
+        return getDataTable(list);
+    }
+
+
+    /**
+     * 获取志愿者提现申请记录详细信息
+     */
+    @ApiOperation("获取志愿者提现申请记录详细信息")
+    @GetMapping(value = "/{volunteerTakeRecordId}")
+    public R<VolunteerTakeRecord> getInfo(@PathVariable("volunteerTakeRecordId") Long volunteerTakeRecordId)
+    {
+        return R.ok(volunteerTakeRecordService.selectVolunteerTakeRecordByVolunteerTakeRecordId(volunteerTakeRecordId));
+    }
+
+    /**
+     * 提现审批
+     */
+    @ApiOperation(value = "提现审批",notes = "传入当前行主键volunteerTakeRecordId,审批状态appStatus:2通过,3拒绝,驳回原因rejectReason,状态为3则必填")
+    @PostMapping("/approval")
+    public R approval(@RequestBody VolunteerTakeRecord takeRecord){
+        String appStatus = takeRecord.getAppStatus();
+        if ("3".equals(appStatus) && StrUtil.isBlank(takeRecord.getRejectReason())){
+            return R.fail("请填写驳回原因");
+        }
+        volunteerTakeRecordService.update(new LambdaUpdateWrapper<VolunteerTakeRecord>()
+                .eq(VolunteerTakeRecord::getVolunteerTakeRecordId,takeRecord.getVolunteerTakeRecordId())
+                .set(VolunteerTakeRecord::getAppStatus,takeRecord.getAppStatus())
+                .set(StrUtil.isNotBlank(takeRecord.getRejectReason()),VolunteerTakeRecord::getRejectReason,takeRecord.getRejectReason())
+                .set(VolunteerTakeRecord::getAppUserId, SecurityUtils.getUserId())
+                .set(VolunteerTakeRecord::getAppUserName,SecurityUtils.getUsername()));
+        return R.ok();
+    }
+
+}

+ 90 - 0
leromro-core/src/main/java/com/leromro/core/domain/VolunteerPaymentRecords.java

@@ -0,0 +1,90 @@
+package com.leromro.core.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.leromro.common.annotation.Excel;
+import com.leromro.common.core.domain.BaseEntity;
+
+/**
+ * 志愿者打款单记录对象 l_volunteer_payment_records
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("l_volunteer_payment_records")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "VolunteerPaymentRecords", description = "志愿者打款单记录")
+public class VolunteerPaymentRecords extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+    private Long volunteerPaymentRecordsId;
+
+    @TableField("payment_order_number")
+    @ApiModelProperty("打款单单号")
+    private String paymentOrderNumber;
+
+    @TableField("is_verified")
+    @ApiModelProperty("是否验证,0为未验证,1为已验证")
+    private String isVerified;
+
+    @TableField("payment_status")
+    @ApiModelProperty("打款状态,1为待打款,2为全部已打款,3为部分已打款,4为全部打款失败,5为撤销打款单")
+    private String paymentStatus;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @TableField("payment_time")
+    @ApiModelProperty("打款时间")
+    private Date paymentTime;
+
+    @TableField("failed_payment_attempts")
+    @ApiModelProperty("打款失败次数")
+    private Integer failedPaymentAttempts;
+
+    @TableField("failed_payment_reason")
+    @ApiModelProperty("打款失败原因")
+    private String failedPaymentReason;
+
+    @TableField("deleted")
+    @ApiModelProperty("是否删除,0为未删除,1为已删除")
+    private String deleted;
+
+    @TableField("total_payment_amount")
+    @ApiModelProperty("打款单总金额")
+    private BigDecimal totalPaymentAmount;
+
+    @TableField("actual_payment_amount")
+    @ApiModelProperty("实际打款金额")
+    private BigDecimal actualPaymentAmount;
+
+    @TableField("successful_payment_amount")
+    @ApiModelProperty("打款成功金额")
+    private BigDecimal successfulPaymentAmount;
+
+    @TableField("failed_payment_amount")
+    @ApiModelProperty("打款失败金额")
+    private BigDecimal failedPaymentAmount;
+
+    @TableField("json_content")
+    @ApiModelProperty("打款失败原因")
+    private String jsonContent;
+
+    @TableField("pay_type")
+    @ApiModelProperty("打款方式(1-银行卡;2-支付宝)")
+    private String payType;
+
+
+}

+ 160 - 0
leromro-core/src/main/java/com/leromro/core/domain/VolunteerTakeRecord.java

@@ -0,0 +1,160 @@
+package com.leromro.core.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.leromro.common.annotation.Excel;
+import com.leromro.common.core.domain.BaseEntity;
+
+/**
+ * 志愿者提现申请记录对象 l_volunteer_take_record
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("l_volunteer_take_record")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "VolunteerTakeRecord", description = "志愿者提现申请记录")
+public class VolunteerTakeRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+    private Long volunteerTakeRecordId;
+
+    @TableField("take_sn")
+    @ApiModelProperty("提现记录编号(TX开头)")
+    private String takeSn;
+
+    @TableField("volunteer_account_id")
+    @ApiModelProperty("志愿者账户id")
+    private Long volunteerAccountId;
+
+    @TableField("volunteer_user_id")
+    @ApiModelProperty("志愿者用户表id")
+    private Long volunteerUserId;
+
+    @TableField("take_amount")
+    @ApiModelProperty("提现申请金额")
+    private BigDecimal takeAmount;
+
+    @TableField("shoud_amount")
+    @ApiModelProperty("提现应发金额(扣除税点)")
+    private BigDecimal shoudAmount;
+
+    @TableField("tax_amount")
+    @ApiModelProperty("扣除的税额")
+    private BigDecimal taxAmount;
+
+    @TableField("receive_amount")
+    @ApiModelProperty("提现实发金额")
+    private BigDecimal receiveAmount;
+
+    @TableField("pay_type")
+    @ApiModelProperty("打款方式(1-银行卡;2-支付宝)")
+    private String payType;
+
+    @TableField("bank_name")
+    @ApiModelProperty("银行名称")
+    private String bankName;
+
+    @TableField("bank_code")
+    @ApiModelProperty("银行代码")
+    private String bankCode;
+
+    @TableField("bank_card_user")
+    @ApiModelProperty("开卡人姓名")
+    private String bankCardUser;
+
+    @TableField("bank_card_sn")
+    @ApiModelProperty("银行卡号")
+    private String bankCardSn;
+
+    @TableField("bank_card_address")
+    @ApiModelProperty("银行卡开户地")
+    private String bankCardAddress;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @TableField("pay_time")
+    @ApiModelProperty("打款时间")
+    private Date payTime;
+
+    @TableField("pay_note")
+    @ApiModelProperty("打款备注")
+    private String payNote;
+
+    @TableField("pay_name")
+    @ApiModelProperty("打款人姓名")
+    private String payName;
+
+    @TableField("is_pay")
+    @ApiModelProperty("0-未打款;1-已打款;2-打款失败")
+    private String isPay;
+
+    @TableField("pay_sn")
+    @ApiModelProperty("打款流水号")
+    private String paySn;
+
+    @TableField("pay_voucher_pics")
+    @ApiModelProperty("打款凭证")
+    private String payVoucherPics;
+
+    @TableField("deleted")
+    @ApiModelProperty("是否删除,0-未删除;1-删除;")
+    private String deleted;
+
+    @TableField("alipay_account_no")
+    @ApiModelProperty("支付宝账户")
+    private String alipayAccountNo;
+
+    @TableField("alipay_name")
+    @ApiModelProperty("支付宝姓名")
+    private String alipayName;
+
+    @TableField("payment_record_id")
+    @ApiModelProperty("志愿者打款单记录表id")
+    private Long paymentRecordId;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @TableField("last_time")
+    @ApiModelProperty("最后打款日期")
+    private Date lastTime;
+
+    @TableField("pay_code")
+    @ApiModelProperty("支付结果码")
+    private String payCode;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @TableField("app_time")
+    @ApiModelProperty("审核时间")
+    private Date appTime;
+
+    @TableField("app_status")
+    @ApiModelProperty("审核状态(1-待审核;2-审核通过;3-审核未通过; 4已撤销)")
+    private String appStatus;
+
+    @TableField("app_user_id")
+    @ApiModelProperty("审核用户id")
+    private String appUserId;
+
+    @TableField("app_user_name")
+    @ApiModelProperty("审核用户姓名")
+    private String appUserName;
+
+    @TableField("reject_reason")
+    @ApiModelProperty("驳回原因")
+    private String rejectReason;
+
+
+}

+ 16 - 0
leromro-core/src/main/java/com/leromro/core/domain/dto/AddPaymentRecordDTO.java

@@ -0,0 +1,16 @@
+package com.leromro.core.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AddPaymentRecordDTO {
+
+    @ApiModelProperty("支付类型1银行卡2支付宝")
+    private String payType;
+
+    @ApiModelProperty("志愿者提现申请单id逗号拼接")
+    private List<Long> ids;
+}

+ 56 - 0
leromro-core/src/main/java/com/leromro/core/domain/dto/VolunteerSubmitAmountDTO.java

@@ -0,0 +1,56 @@
+package com.leromro.core.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.math.BigDecimal;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Range;
+
+@Data
+@ApiModel(description = "志愿者账户提现申请模型")
+public class VolunteerSubmitAmountDTO {
+
+    @NotBlank(message = "打款方式不能为空")
+    @Range(min = 1, max = 2, message = "打款方式(1-银行卡;2-支付宝;)")
+    @ApiModelProperty(value = "打款方式(1-银行卡;2-支付宝;)", name = "payType", example = "1")
+    private String payType;
+
+    @DecimalMin(value = "0.01", message = "提现申请金额最小值为0.01")
+    @Digits(integer = 10, fraction = 2, message = "提现申请金额小数位上限为2位")
+    @ApiModelProperty(value = "提现申请金额", name = "takeAmount", example = "10")
+    @NotNull(message = "提现申请金额不能为空")
+    private BigDecimal takeAmount;
+
+    @ApiModelProperty(value = "银行名称", name = "bankName", example = "1")
+    private String bankName;
+
+    @ApiModelProperty(value = "银行代码", name = "bankCode", example = "1")
+    private String bankCode;
+
+    @ApiModelProperty(value = "开卡人姓名", name = "bankCardUser", example = "1")
+    private String bankCardUser;
+
+    @ApiModelProperty(value = "银行卡号", name = "bankCardSn", example = "1")
+    private String bankCardSn;
+
+    @ApiModelProperty(value = "银行卡开户地", name = "bankCardAddress", example = "1")
+    private String bankCardAddress;
+
+    @ApiModelProperty(value = "备注", name = "note", required = true, example = "")
+    private String note;
+
+    @ApiModelProperty(value = "支付宝账户", name = "alipayAccountNo", example = "101123340")
+    private String alipayAccountNo;
+
+    @ApiModelProperty(value = "支付宝姓名", name = "alipayName", example = "ali")
+    private String alipayName;
+
+    @ApiModelProperty(value = "强制版本", name = "forcedVersion", notes = "传值为1时,为新版本提现", example = "1")
+    private String forcedVersion;
+
+}

+ 56 - 0
leromro-core/src/main/java/com/leromro/core/domain/dto/WithdrawPaymentDTO.java

@@ -0,0 +1,56 @@
+package com.leromro.core.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.util.List;
+
+import lombok.Data;
+
+@Data
+@ApiModel(description = "打款单提现查询参数")
+/* loaded from: jc-api-1.0.0.jar:org/jjr/jc/api/vo/admin/driver/WithdrawPaymentVo.class */
+public class WithdrawPaymentDTO {
+
+    @ApiModelProperty(value = "分页页数", name = "pageNum", required = false, example = "1")
+    private Integer pageNum;
+
+    @ApiModelProperty(value = "分页长度", name = "pageSize", required = false, example = "10")
+    private Integer pageSize;
+
+    @ApiModelProperty(value = "打款单单号", name = "paymentOrderNum", example = "1")
+    private String paymentOrderNum;
+
+    @ApiModelProperty(value = "打款状态", name = "payStatus", example = "1", notes = "1为待打款,2为全部已打款,3为部分已打款,4为全部打款失败")
+    private String payStatus;
+
+    @ApiModelProperty(value = "验证状态", name = "checkStatus", example = "1", notes = "0为未验证,1为已验证")
+    private String checkStatus;
+
+    @ApiModelProperty(value = "生成开始时间", name = "createStartTime", example = "2024-04-01 00:00:00", notes = "yyyy-MM-dd HH:mm:ss")
+    private String createStartTime;
+
+    @ApiModelProperty(value = "生成结束时间", name = "createEndTime", example = "2024-04-02 00:00:00", notes = "yyyy-MM-dd HH:mm:ss")
+    private String createEndTime;
+
+    @ApiModelProperty(value = "生成开始时间", name = "payStartTime", example = "2024-04-01 00:00:00", notes = "yyyy-MM-dd HH:mm:ss")
+    private String payStartTime;
+
+    @ApiModelProperty(value = "生成结束时间", name = "payEndTime", example = "2024-04-02 00:00:00", notes = "yyyy-MM-dd HH:mm:ss")
+    private String payEndTime;
+
+    @ApiModelProperty(value = "打款状态", name = "isPay", example = "1")
+    private String isPay;
+
+    @ApiModelProperty(value = "打款单id", name = "volunteerPaymentRecordsId", example = "1")
+    private Long volunteerPaymentRecordsId;
+
+    @ApiModelProperty(value = "打款验证密码", name = "payPassword", example = "1")
+    private String payPassword;
+
+    @ApiModelProperty(value = "打款方式(1-银行卡;2-支付宝)", name = "payType", example = "1")
+    private String payType;
+
+    @ApiModelProperty(value = "打款单ids", name = "paymentIds", example = "1", hidden = true)
+    private List<String> paymentIds;
+
+}

+ 29 - 0
leromro-core/src/main/java/com/leromro/core/domain/vo/AlipayCashWithdrawal.java

@@ -0,0 +1,29 @@
+package com.leromro.core.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(description = "支付宝提现参数")
+public class AlipayCashWithdrawal {
+
+    @ApiModelProperty(value = "商家侧唯一订单号,由商家自定义", name = "outBizNo", example = "xxx")
+    private String outBizNo;
+
+    @ApiModelProperty(value = "业务备注", name = "remark", example = "xx")
+    private String remark;
+
+    @ApiModelProperty(value = "参与方的唯一标识(支付宝账号", name = "identity", example = "")
+    private String identity;
+
+    @ApiModelProperty(value = "参与方真实姓名", name = "name", example = "")
+    private String name;
+
+    @ApiModelProperty(value = "订单总金额", name = "transAmount", example = "")
+    private String transAmount;
+
+    @ApiModelProperty(value = "转账业务的标题", name = "orderTitle", example = "")
+    private String orderTitle;
+
+}

+ 9 - 2
leromro-core/src/main/java/com/leromro/core/domain/vo/VolunteerAccountChangeVO.java

@@ -2,8 +2,15 @@ package com.leromro.core.domain.vo;
 
 import com.leromro.core.domain.VolunteerAccountChange;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
 
+@EqualsAndHashCode(callSuper = true)
+@Data
 public class VolunteerAccountChangeVO extends VolunteerAccountChange {
-    @ApiModelProperty("服务名称")
-    private String businessTierName;
+
+    @ApiModelProperty("0-未打款;1-已打款;2-打款失败")
+    private String isPay;
+
+
 }

+ 90 - 0
leromro-core/src/main/java/com/leromro/core/facade/VolunteerAccountFacade.java

@@ -0,0 +1,90 @@
+package com.leromro.core.facade;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.leromro.common.core.domain.R;
+import com.leromro.common.utils.SecurityUtils;
+import com.leromro.core.domain.VolunteerAccount;
+import com.leromro.core.domain.VolunteerAccountChange;
+import com.leromro.core.domain.VolunteerTakeRecord;
+import com.leromro.core.domain.dto.VolunteerSubmitAmountDTO;
+import com.leromro.core.service.IVolunteerAccountChangeService;
+import com.leromro.core.service.IVolunteerAccountService;
+import com.leromro.core.service.IVolunteerTakeRecordService;
+import com.leromro.core.utils.BigDecimalUtil;
+import com.leromro.core.utils.NoUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+
+@Slf4j
+@Service
+public class VolunteerAccountFacade {
+
+    @Autowired
+    private IVolunteerAccountService volunteerAccountService;
+
+    @Autowired
+    private IVolunteerTakeRecordService volunteerTakeRecordService;
+
+    @Autowired
+    private IVolunteerAccountChangeService accountChangeService;
+
+
+    /**
+     * 提交提现申请
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public R submitAmountApply(VolunteerSubmitAmountDTO dto) {
+        //查询志愿者账户,判断账户余额是否足够
+        VolunteerAccount account = volunteerAccountService.getOne(new LambdaQueryWrapper<VolunteerAccount>()
+                .eq(VolunteerAccount::getVolunteerId, SecurityUtils.getUserId()));
+        if (ObjectUtil.isNull(account)){
+            return R.fail("当前志愿者账户不存在");
+        }
+        if (account.getBalance().compareTo(dto.getTakeAmount()) < 0){
+            return R.fail("账户余额不足");
+        }
+        //修改志愿者账户余额
+        BigDecimal changeBeforeBalance = account.getBalance();
+        account.setBalance(account.getBalance().subtract(dto.getTakeAmount()));
+        account.setBeBalance(account.getBeBalance().add(dto.getTakeAmount()));
+        volunteerAccountService.updateById(account);
+        //生成志愿者提现申请记录
+        VolunteerTakeRecord takeRecord = VolunteerTakeRecord.builder()
+                .takeSn(NoUtil.getTakeMoneyNo())
+                .volunteerAccountId(account.getVolunteerAccountId())
+                .volunteerUserId(SecurityUtils.getUserId())
+                .takeAmount(dto.getTakeAmount())
+                .shoudAmount(dto.getTakeAmount())
+                .taxAmount(BigDecimal.ZERO)
+                .payType(dto.getPayType())
+                .alipayAccountNo(dto.getAlipayAccountNo())
+                .alipayName(dto.getAlipayName())
+                .build();
+        volunteerTakeRecordService.save(takeRecord);
+        //修改账户变更记录表
+        VolunteerAccountChange accountChange = VolunteerAccountChange.builder()
+                .volunteerId(SecurityUtils.getUserId())
+                .changeType("0")
+                .sourceType("10")
+                .changeMoney(dto.getTakeAmount())
+                .beforeBalance(changeBeforeBalance)
+                .afterBalance(account.getBalance())
+                .sourceId(takeRecord.getVolunteerTakeRecordId())
+                .build();
+        accountChangeService.save(accountChange);
+        return R.ok();
+    }
+
+
+    public R getWithdrawStatus() {
+        int count = volunteerTakeRecordService.count(new LambdaQueryWrapper<VolunteerTakeRecord>()
+                .eq(VolunteerTakeRecord::getVolunteerUserId, SecurityUtils.getUserId())
+                .eq(VolunteerTakeRecord::getAppStatus, "1"));
+        return count>0?R.fail("提现审批中"):R.ok();
+    }
+}

+ 65 - 0
leromro-core/src/main/java/com/leromro/core/facade/VolunteerPaymentRecordsFacade.java

@@ -0,0 +1,65 @@
+package com.leromro.core.facade;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.leromro.common.core.domain.R;
+import com.leromro.common.core.domain.entity.SysUser;
+import com.leromro.common.core.redis.RedisCache;
+import com.leromro.common.enums.ConstantsKey;
+import com.leromro.common.exception.ServiceException;
+import com.leromro.common.utils.SecurityUtils;
+import com.leromro.core.domain.VolunteerPaymentRecords;
+import com.leromro.core.domain.dto.WithdrawPaymentDTO;
+import com.leromro.core.service.IVolunteerPaymentRecordsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+@Service
+public class VolunteerPaymentRecordsFacade {
+
+    @Autowired
+    private IVolunteerPaymentRecordsService volunteerPaymentRecordsService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    /**
+     * 打款单验证
+     */
+    public R payoutCheck(WithdrawPaymentDTO dto) {
+        //校验是否有打款权限
+        SysUser user = SecurityUtils.getLoginUser().getUser();
+        if (user.getDeptId() != 100){
+            return R.fail("当前用户没有打款权限");
+        }
+        //todo 校验短信
+        //新增,则校验手机号
+        String redisCode = this.redisCache.getCacheObject(ConstantsKey.REDIS_PHONE_CODE.getKey() + "_" + user.getPhonenumber());
+        if (StrUtil.isBlank(redisCode)) {
+            return R.fail("验证码已过期");
+        }
+        if (!redisCode.equals(dto.getPayPassword())) {
+            return R.fail("验证码错误");
+        }
+        //查询打款单,查看是否已经打款
+        VolunteerPaymentRecords paymentRecords = volunteerPaymentRecordsService.getById(dto.getVolunteerPaymentRecordsId());
+        if (ObjectUtil.isNull(paymentRecords)){
+            return R.fail("打款单不存在");
+        }
+        if (!"1".equals(paymentRecords.getPaymentStatus())){
+            return R.fail("该打款单状态错误");
+        }
+        if ("1".equals(paymentRecords.getIsVerified())){
+            return R.fail("该打款单已经验证");
+        }
+        paymentRecords.setIsVerified("1");
+        paymentRecords.setPaymentStatus("1");
+        paymentRecords.setPaymentTime(new Date());
+        volunteerPaymentRecordsService.updateById(paymentRecords);
+        //异步执行打款
+        volunteerPaymentRecordsService.asyncPayment(dto.getVolunteerPaymentRecordsId());
+        return R.ok();
+    }
+}

+ 62 - 0
leromro-core/src/main/java/com/leromro/core/mapper/VolunteerPaymentRecordsMapper.java

@@ -0,0 +1,62 @@
+package com.leromro.core.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.leromro.core.domain.VolunteerPaymentRecords;
+
+/**
+ * 志愿者打款单记录Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+public interface VolunteerPaymentRecordsMapper extends BaseMapper<VolunteerPaymentRecords>
+{
+    /**
+     * 查询志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsId 志愿者打款单记录主键
+     * @return 志愿者打款单记录
+     */
+    public VolunteerPaymentRecords selectVolunteerPaymentRecordsByVolunteerPaymentRecordsId(Long volunteerPaymentRecordsId);
+
+    /**
+     * 查询志愿者打款单记录列表
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 志愿者打款单记录集合
+     */
+    public List<VolunteerPaymentRecords> selectVolunteerPaymentRecordsList(VolunteerPaymentRecords volunteerPaymentRecords);
+
+    /**
+     * 新增志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 结果
+     */
+    public int insertVolunteerPaymentRecords(VolunteerPaymentRecords volunteerPaymentRecords);
+
+    /**
+     * 修改志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 结果
+     */
+    public int updateVolunteerPaymentRecords(VolunteerPaymentRecords volunteerPaymentRecords);
+
+    /**
+     * 删除志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsId 志愿者打款单记录主键
+     * @return 结果
+     */
+    public int deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsId(Long volunteerPaymentRecordsId);
+
+    /**
+     * 批量删除志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsIds(Long[] volunteerPaymentRecordsIds);
+}

+ 62 - 0
leromro-core/src/main/java/com/leromro/core/mapper/VolunteerTakeRecordMapper.java

@@ -0,0 +1,62 @@
+package com.leromro.core.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.leromro.core.domain.VolunteerTakeRecord;
+
+/**
+ * 志愿者提现申请记录Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+public interface VolunteerTakeRecordMapper extends BaseMapper<VolunteerTakeRecord>
+{
+    /**
+     * 查询志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordId 志愿者提现申请记录主键
+     * @return 志愿者提现申请记录
+     */
+    public VolunteerTakeRecord selectVolunteerTakeRecordByVolunteerTakeRecordId(Long volunteerTakeRecordId);
+
+    /**
+     * 查询志愿者提现申请记录列表
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 志愿者提现申请记录集合
+     */
+    public List<VolunteerTakeRecord> selectVolunteerTakeRecordList(VolunteerTakeRecord volunteerTakeRecord);
+
+    /**
+     * 新增志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 结果
+     */
+    public int insertVolunteerTakeRecord(VolunteerTakeRecord volunteerTakeRecord);
+
+    /**
+     * 修改志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 结果
+     */
+    public int updateVolunteerTakeRecord(VolunteerTakeRecord volunteerTakeRecord);
+
+    /**
+     * 删除志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordId 志愿者提现申请记录主键
+     * @return 结果
+     */
+    public int deleteVolunteerTakeRecordByVolunteerTakeRecordId(Long volunteerTakeRecordId);
+
+    /**
+     * 批量删除志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteVolunteerTakeRecordByVolunteerTakeRecordIds(Long[] volunteerTakeRecordIds);
+}

+ 71 - 0
leromro-core/src/main/java/com/leromro/core/service/IVolunteerPaymentRecordsService.java

@@ -0,0 +1,71 @@
+package com.leromro.core.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.leromro.common.core.domain.R;
+import com.leromro.core.domain.VolunteerPaymentRecords;
+import com.leromro.core.domain.dto.AddPaymentRecordDTO;
+import com.leromro.core.domain.dto.WithdrawPaymentDTO;
+
+/**
+ * 志愿者打款单记录Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+public interface IVolunteerPaymentRecordsService extends IService<VolunteerPaymentRecords>
+{
+    /**
+     * 查询志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsId 志愿者打款单记录主键
+     * @return 志愿者打款单记录
+     */
+    public VolunteerPaymentRecords selectVolunteerPaymentRecordsByVolunteerPaymentRecordsId(Long volunteerPaymentRecordsId);
+
+    /**
+     * 查询志愿者打款单记录列表
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 志愿者打款单记录集合
+     */
+    public List<VolunteerPaymentRecords> selectVolunteerPaymentRecordsList(VolunteerPaymentRecords volunteerPaymentRecords);
+
+    /**
+     * 新增志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 结果
+     */
+    public Boolean insertVolunteerPaymentRecords(VolunteerPaymentRecords volunteerPaymentRecords);
+
+    /**
+     * 修改志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 结果
+     */
+    public Boolean updateVolunteerPaymentRecords(VolunteerPaymentRecords volunteerPaymentRecords);
+
+    /**
+     * 批量删除志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsIds 需要删除的志愿者打款单记录主键集合
+     * @return 结果
+     */
+    public int deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsIds(Long[] volunteerPaymentRecordsIds);
+
+    /**
+     * 删除志愿者打款单记录信息
+     * 
+     * @param volunteerPaymentRecordsId 志愿者打款单记录主键
+     * @return 结果
+     */
+    public int deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsId(Long volunteerPaymentRecordsId);
+
+    R addPaymentRecord(AddPaymentRecordDTO dto);
+
+    //异步打款
+    void asyncPayment(Long volunteerPaymentRecordsId);
+
+}

+ 62 - 0
leromro-core/src/main/java/com/leromro/core/service/IVolunteerTakeRecordService.java

@@ -0,0 +1,62 @@
+package com.leromro.core.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.leromro.core.domain.VolunteerTakeRecord;
+
+/**
+ * 志愿者提现申请记录Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+public interface IVolunteerTakeRecordService extends IService<VolunteerTakeRecord>
+{
+    /**
+     * 查询志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordId 志愿者提现申请记录主键
+     * @return 志愿者提现申请记录
+     */
+    public VolunteerTakeRecord selectVolunteerTakeRecordByVolunteerTakeRecordId(Long volunteerTakeRecordId);
+
+    /**
+     * 查询志愿者提现申请记录列表
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 志愿者提现申请记录集合
+     */
+    public List<VolunteerTakeRecord> selectVolunteerTakeRecordList(VolunteerTakeRecord volunteerTakeRecord);
+
+    /**
+     * 新增志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 结果
+     */
+    public Boolean insertVolunteerTakeRecord(VolunteerTakeRecord volunteerTakeRecord);
+
+    /**
+     * 修改志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 结果
+     */
+    public Boolean updateVolunteerTakeRecord(VolunteerTakeRecord volunteerTakeRecord);
+
+    /**
+     * 批量删除志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordIds 需要删除的志愿者提现申请记录主键集合
+     * @return 结果
+     */
+    public int deleteVolunteerTakeRecordByVolunteerTakeRecordIds(Long[] volunteerTakeRecordIds);
+
+    /**
+     * 删除志愿者提现申请记录信息
+     * 
+     * @param volunteerTakeRecordId 志愿者提现申请记录主键
+     * @return 结果
+     */
+    public int deleteVolunteerTakeRecordByVolunteerTakeRecordId(Long volunteerTakeRecordId);
+}

+ 295 - 0
leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerPaymentRecordsServiceImpl.java

@@ -0,0 +1,295 @@
+package com.leromro.core.service.impl;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.domain.AlipayFundTransUniTransferModel;
+import com.alipay.api.domain.Participant;
+import com.alipay.api.request.AlipayFundTransUniTransferRequest;
+import com.alipay.api.response.AlipayFundTransUniTransferResponse;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.exceptions.ApiException;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.leromro.common.core.domain.R;
+import com.leromro.common.core.domain.entity.SysUser;
+import com.leromro.common.utils.SecurityUtils;
+import com.leromro.core.domain.VolunteerAccount;
+import com.leromro.core.domain.VolunteerTakeRecord;
+import com.leromro.core.domain.dto.AddPaymentRecordDTO;
+import com.leromro.core.domain.dto.WithdrawPaymentDTO;
+import com.leromro.core.domain.vo.AlipayCashWithdrawal;
+import com.leromro.core.mapper.VolunteerPaymentRecordsMapper;
+import com.leromro.common.utils.DateUtils;
+import com.leromro.core.service.IVolunteerAccountService;
+import com.leromro.core.service.IVolunteerTakeRecordService;
+import com.leromro.core.utils.NoUtil;
+import com.leromro.core.utils.SendSmsUtil;
+import com.leromro.framework.config.ConstantsConfig;
+import com.leromro.system.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import com.leromro.core.mapper.VolunteerPaymentRecordsMapper;
+import com.leromro.core.domain.VolunteerPaymentRecords;
+import com.leromro.core.service.IVolunteerPaymentRecordsService;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 志愿者打款单记录Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+@Slf4j
+@Service
+public class VolunteerPaymentRecordsServiceImpl extends ServiceImpl<VolunteerPaymentRecordsMapper, VolunteerPaymentRecords> implements IVolunteerPaymentRecordsService
+{
+    @Autowired
+    private VolunteerPaymentRecordsMapper volunteerPaymentRecordsMapper;
+
+    @Autowired
+    private IVolunteerTakeRecordService takeRecordService;
+
+    @Autowired
+    private IVolunteerAccountService volunteerAccountService;
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    @Qualifier("aliPayService")
+    private AlipayClient alipayClient;
+
+    /**
+     * 查询志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsId 志愿者打款单记录主键
+     * @return 志愿者打款单记录
+     */
+    @Override
+    public VolunteerPaymentRecords selectVolunteerPaymentRecordsByVolunteerPaymentRecordsId(Long volunteerPaymentRecordsId)
+    {
+        return volunteerPaymentRecordsMapper.selectVolunteerPaymentRecordsByVolunteerPaymentRecordsId(volunteerPaymentRecordsId);
+    }
+
+    /**
+     * 查询志愿者打款单记录列表
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 志愿者打款单记录
+     */
+    @Override
+    public List<VolunteerPaymentRecords> selectVolunteerPaymentRecordsList(VolunteerPaymentRecords volunteerPaymentRecords)
+    {
+        return volunteerPaymentRecordsMapper.selectVolunteerPaymentRecordsList(volunteerPaymentRecords);
+    }
+
+    /**
+     * 新增志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 结果
+     */
+    @Override
+    public Boolean insertVolunteerPaymentRecords(VolunteerPaymentRecords volunteerPaymentRecords)
+    {
+        return this.save(volunteerPaymentRecords);
+    }
+
+    /**
+     * 修改志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecords 志愿者打款单记录
+     * @return 结果
+     */
+    @Override
+    public Boolean updateVolunteerPaymentRecords(VolunteerPaymentRecords volunteerPaymentRecords)
+    {
+        return this.updateById(volunteerPaymentRecords);
+    }
+
+    /**
+     * 批量删除志愿者打款单记录
+     * 
+     * @param volunteerPaymentRecordsIds 需要删除的志愿者打款单记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsIds(Long[] volunteerPaymentRecordsIds)
+    {
+        return volunteerPaymentRecordsMapper.deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsIds(volunteerPaymentRecordsIds);
+    }
+
+    /**
+     * 删除志愿者打款单记录信息
+     * 
+     * @param volunteerPaymentRecordsId 志愿者打款单记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsId(Long volunteerPaymentRecordsId)
+    {
+        return volunteerPaymentRecordsMapper.deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsId(volunteerPaymentRecordsId);
+    }
+
+    /**
+     * 创建志愿者打款单
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public R addPaymentRecord(AddPaymentRecordDTO dto) {
+        BigDecimal totalPaymentAmount = BigDecimal.ZERO;
+        BigDecimal actualPaymentAmount = BigDecimal.ZERO;
+        //获取所有打款单
+        List<VolunteerTakeRecord> records = takeRecordService.listByIds(dto.getIds());
+        //判断打款状态,并统计总金额
+        for (VolunteerTakeRecord record : records) {
+            if (!dto.getPayType().equals(record.getPayType())){
+                return R.fail("提现申请单"+record.getTakeSn()+"打款类型不一致");
+            }
+            if (!"2".equals(record.getAppStatus())){
+                return R.fail("提现申请单"+record.getTakeSn()+"审批状态错误");
+            }
+            totalPaymentAmount = totalPaymentAmount.add(record.getTakeAmount());
+            actualPaymentAmount = actualPaymentAmount.add(record.getShoudAmount());
+        }
+        VolunteerPaymentRecords paymentRecords = new VolunteerPaymentRecords();
+        paymentRecords.setPaymentOrderNumber(NoUtil.getTakeMoneyNo());
+        paymentRecords.setTotalPaymentAmount(totalPaymentAmount);
+        paymentRecords.setActualPaymentAmount(actualPaymentAmount);
+        paymentRecords.setPayType(dto.getPayType());
+        this.save(paymentRecords);
+        //批量修改提现申请单,设置打款单id
+        takeRecordService.update(new LambdaUpdateWrapper<VolunteerTakeRecord>()
+                .set(VolunteerTakeRecord::getPaymentRecordId, paymentRecords.getVolunteerPaymentRecordsId())
+                .in(VolunteerTakeRecord::getVolunteerTakeRecordId, dto.getIds()));
+        return R.ok();
+    }
+
+    @Async("threadPoolTaskExecutor")
+    @Override
+    public void asyncPayment(Long volunteerPaymentRecordsId) {
+        //查询打款单对应的申请单信息
+        List<VolunteerTakeRecord> beforeRecords = takeRecordService.list(new LambdaQueryWrapper<VolunteerTakeRecord>()
+                .eq(VolunteerTakeRecord::getPaymentRecordId, volunteerPaymentRecordsId));
+        //循环打款
+        for (VolunteerTakeRecord record : beforeRecords) {
+            takeAmountByAlipay(record);
+        }
+        //再次查询所有申请单,判断是否已经全部打款,全部打款金额
+        List<VolunteerTakeRecord> afterRecords = takeRecordService.list(new LambdaQueryWrapper<VolunteerTakeRecord>()
+                .eq(VolunteerTakeRecord::getPaymentRecordId, volunteerPaymentRecordsId));
+        VolunteerPaymentRecords drvPaymentRecords = new VolunteerPaymentRecords();
+        drvPaymentRecords.setVolunteerPaymentRecordsId(volunteerPaymentRecordsId);
+        int total = afterRecords.size();
+        long prepareNum = afterRecords.stream().filter(record -> {
+            return "0".equals(record.getIsPay());
+        }).count();
+        long successNum = afterRecords.stream().filter(record2 -> {
+            return "1".equals(record2.getIsPay());
+        }).count();
+        long failedNum = afterRecords.stream().filter(record3 -> {
+            return "2".equals(record3.getIsPay());
+        }).count();
+
+        if (total == prepareNum) {
+            drvPaymentRecords.setPaymentStatus("1");
+        } else if (total == successNum) {
+            drvPaymentRecords.setPaymentStatus("2");
+        } else if (total > successNum + failedNum) {
+            drvPaymentRecords.setPaymentStatus("3");
+        } else if (total == failedNum) {
+            drvPaymentRecords.setPaymentStatus("4");
+        }
+
+        BigDecimal successAmount = (BigDecimal) afterRecords.stream().filter(v -> {
+            return "1".equals(v.getIsPay());
+        }).map(VolunteerTakeRecord::getShoudAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal failedAmount = (BigDecimal) afterRecords.stream().filter(v2 -> {
+            return "2".equals(v2.getIsPay());
+        }).map(VolunteerTakeRecord::getShoudAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        drvPaymentRecords.setSuccessfulPaymentAmount(successAmount);
+        drvPaymentRecords.setFailedPaymentAmount(failedAmount);
+        this.updateById(drvPaymentRecords);
+    }
+
+    private void takeAmountByAlipay(VolunteerTakeRecord takeAmountRecord) {
+        AlipayCashWithdrawal withdrawal = new AlipayCashWithdrawal();
+        withdrawal.setIdentity(takeAmountRecord.getAlipayAccountNo());
+        withdrawal.setName(takeAmountRecord.getAlipayName());
+        withdrawal.setTransAmount(takeAmountRecord.getShoudAmount().toString());
+        withdrawal.setOutBizNo(takeAmountRecord.getTakeSn());
+        withdrawal.setRemark("提现");
+        withdrawal.setOrderTitle("提现转账");
+        try {
+            AlipayFundTransUniTransferResponse response = this.alipayCashWithdrawal(withdrawal);
+            if (response.isSuccess()) {
+                System.out.println("========提现转账调用成功========");
+                //修改账户提现中的金额
+                VolunteerAccount driverAccount = volunteerAccountService.getById(takeAmountRecord.getVolunteerAccountId());
+                BigDecimal subtract = driverAccount.getBeBalance().subtract(takeAmountRecord.getTakeAmount());
+                driverAccount.setBeBalance(subtract.compareTo(BigDecimal.ZERO) < 0 ? new BigDecimal(BigInteger.ZERO) : subtract);
+                volunteerAccountService.updateById(driverAccount);
+
+                //修改提现申请单状态
+                takeAmountRecord.setIsPay("1");
+                takeAmountRecord.setPayTime(new Date());
+                takeAmountRecord.setReceiveAmount(takeAmountRecord.getShoudAmount());
+                this.takeRecordService.updateById(takeAmountRecord);
+
+                SysUser user = userService.getById(takeAmountRecord.getVolunteerUserId());
+                JSONObject json = new JSONObject();
+                json.putOnce("time", DateUtil.format(takeAmountRecord.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
+                SendSmsUtil.send(user.getPhonenumber(), json.toString(), ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_WITGDRAW.getValue());
+
+            } else {
+                takeAmountRecord.setIsPay("2");
+                takeAmountRecord.setUpdateTime(new Date());
+                takeAmountRecord.setPayNote(response.getSubMsg());
+                this.takeRecordService.updateById(takeAmountRecord);
+                log.error("支付宝转账失败:{}", response.getSubMsg());
+            }
+        } catch (Exception e) {
+            log.error("支付宝转账调用失败:{}", e.getMessage());
+        }
+    }
+
+    public AlipayFundTransUniTransferResponse alipayCashWithdrawal(AlipayCashWithdrawal vo) throws AlipayApiException {
+        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
+        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
+        model.setOutBizNo(vo.getOutBizNo());
+        model.setRemark(vo.getRemark());
+        model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
+        model.setBizScene("DIRECT_TRANSFER");
+        Participant payeeInfo = new Participant();
+        payeeInfo.setIdentity(vo.getIdentity());
+        payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
+        payeeInfo.setName(vo.getName());
+        model.setPayeeInfo(payeeInfo);
+        model.setTransAmount(vo.getTransAmount());
+        model.setProductCode("TRANS_ACCOUNT_NO_PWD");
+        model.setOrderTitle(vo.getOrderTitle());
+        request.setBizModel(model);
+        AlipayFundTransUniTransferResponse response = (AlipayFundTransUniTransferResponse) this.alipayClient.certificateExecute(request);
+        System.out.println("支付宝提现返回体:" + response.getBody());
+        System.out.println("支付宝提现返回参数:" + JSONUtil.parseObj(response));
+        if (response.isSuccess()) {
+            System.out.println("调用成功");
+        } else {
+            System.out.println("调用失败");
+        }
+        return response;
+    }
+
+}

+ 96 - 0
leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerTakeRecordServiceImpl.java

@@ -0,0 +1,96 @@
+package com.leromro.core.service.impl;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.leromro.core.mapper.VolunteerTakeRecordMapper;
+import com.leromro.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.leromro.core.mapper.VolunteerTakeRecordMapper;
+import com.leromro.core.domain.VolunteerTakeRecord;
+import com.leromro.core.service.IVolunteerTakeRecordService;
+
+/**
+ * 志愿者提现申请记录Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-05-15
+ */
+@Service
+public class VolunteerTakeRecordServiceImpl extends ServiceImpl<VolunteerTakeRecordMapper, VolunteerTakeRecord> implements IVolunteerTakeRecordService
+{
+    @Autowired
+    private VolunteerTakeRecordMapper volunteerTakeRecordMapper;
+
+    /**
+     * 查询志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordId 志愿者提现申请记录主键
+     * @return 志愿者提现申请记录
+     */
+    @Override
+    public VolunteerTakeRecord selectVolunteerTakeRecordByVolunteerTakeRecordId(Long volunteerTakeRecordId)
+    {
+        return volunteerTakeRecordMapper.selectVolunteerTakeRecordByVolunteerTakeRecordId(volunteerTakeRecordId);
+    }
+
+    /**
+     * 查询志愿者提现申请记录列表
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 志愿者提现申请记录
+     */
+    @Override
+    public List<VolunteerTakeRecord> selectVolunteerTakeRecordList(VolunteerTakeRecord volunteerTakeRecord)
+    {
+        return volunteerTakeRecordMapper.selectVolunteerTakeRecordList(volunteerTakeRecord);
+    }
+
+    /**
+     * 新增志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 结果
+     */
+    @Override
+    public Boolean insertVolunteerTakeRecord(VolunteerTakeRecord volunteerTakeRecord)
+    {
+        return this.save(volunteerTakeRecord);
+    }
+
+    /**
+     * 修改志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecord 志愿者提现申请记录
+     * @return 结果
+     */
+    @Override
+    public Boolean updateVolunteerTakeRecord(VolunteerTakeRecord volunteerTakeRecord)
+    {
+        return this.updateById(volunteerTakeRecord);
+    }
+
+    /**
+     * 批量删除志愿者提现申请记录
+     * 
+     * @param volunteerTakeRecordIds 需要删除的志愿者提现申请记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteVolunteerTakeRecordByVolunteerTakeRecordIds(Long[] volunteerTakeRecordIds)
+    {
+        return volunteerTakeRecordMapper.deleteVolunteerTakeRecordByVolunteerTakeRecordIds(volunteerTakeRecordIds);
+    }
+
+    /**
+     * 删除志愿者提现申请记录信息
+     * 
+     * @param volunteerTakeRecordId 志愿者提现申请记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteVolunteerTakeRecordByVolunteerTakeRecordId(Long volunteerTakeRecordId)
+    {
+        return volunteerTakeRecordMapper.deleteVolunteerTakeRecordByVolunteerTakeRecordId(volunteerTakeRecordId);
+    }
+}

+ 8 - 1
leromro-core/src/main/resources/mapper/core/VolunteerAccountChangeMapper.xml

@@ -44,7 +44,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectVolunteerAccountChangeListAndServiceType"
             resultType="com.leromro.core.domain.vo.VolunteerAccountChangeVO"
             parameterType="com.leromro.core.domain.VolunteerAccountChange">
-        select lvac.* from l_volunteer_account_change lvac
+        select lvac.*,
+        case
+            when lvac.source_type = 10 then
+                (select is_pay from l_volunteer_take_record where volunteer_take_record_id = lvac.source_id)
+            else
+                "99"
+        end as isPay
+        from l_volunteer_account_change lvac
         <where>
             <if test="volunteerId != null and volunteerId != ''">and lvac.volunteer_id = #{volunteerId}</if>
             <if test="createTime != null ">

+ 134 - 0
leromro-core/src/main/resources/mapper/core/VolunteerPaymentRecordsMapper.xml

@@ -0,0 +1,134 @@
+<?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.leromro.core.mapper.VolunteerPaymentRecordsMapper">
+    
+    <resultMap type="VolunteerPaymentRecords" id="VolunteerPaymentRecordsResult">
+        <result property="volunteerPaymentRecordsId"    column="volunteer_payment_records_id"    />
+        <result property="paymentOrderNumber"    column="payment_order_number"    />
+        <result property="isVerified"    column="is_verified"    />
+        <result property="paymentStatus"    column="payment_status"    />
+        <result property="paymentTime"    column="payment_time"    />
+        <result property="failedPaymentAttempts"    column="failed_payment_attempts"    />
+        <result property="failedPaymentReason"    column="failed_payment_reason"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="deleted"    column="deleted"    />
+        <result property="totalPaymentAmount"    column="total_payment_amount"    />
+        <result property="actualPaymentAmount"    column="actual_payment_amount"    />
+        <result property="successfulPaymentAmount"    column="successful_payment_amount"    />
+        <result property="failedPaymentAmount"    column="failed_payment_amount"    />
+        <result property="jsonContent"    column="json_content"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="payType"    column="pay_type"    />
+        <result property="createBy"    column="create_by"    />
+    </resultMap>
+
+    <sql id="selectVolunteerPaymentRecordsVo">
+        select * from l_volunteer_payment_records
+    </sql>
+
+    <select id="selectVolunteerPaymentRecordsList" parameterType="VolunteerPaymentRecords" resultMap="VolunteerPaymentRecordsResult">
+        <include refid="selectVolunteerPaymentRecordsVo"/>
+        <where>  
+            <if test="paymentOrderNumber != null  and paymentOrderNumber != ''"> and payment_order_number = #{paymentOrderNumber}</if>
+            <if test="isVerified != null  and isVerified != ''"> and is_verified = #{isVerified}</if>
+            <if test="paymentStatus != null  and paymentStatus != ''"> and payment_status = #{paymentStatus}</if>
+            <if test="paymentTime != null "> and payment_time = #{paymentTime}</if>
+            <if test="failedPaymentAttempts != null "> and failed_payment_attempts = #{failedPaymentAttempts}</if>
+            <if test="failedPaymentReason != null  and failedPaymentReason != ''"> and failed_payment_reason = #{failedPaymentReason}</if>
+            <if test="deleted != null  and deleted != ''"> and deleted = #{deleted}</if>
+            <if test="totalPaymentAmount != null "> and total_payment_amount = #{totalPaymentAmount}</if>
+            <if test="actualPaymentAmount != null "> and actual_payment_amount = #{actualPaymentAmount}</if>
+            <if test="successfulPaymentAmount != null "> and successful_payment_amount = #{successfulPaymentAmount}</if>
+            <if test="failedPaymentAmount != null "> and failed_payment_amount = #{failedPaymentAmount}</if>
+            <if test="jsonContent != null  and jsonContent != ''"> and json_content = #{jsonContent}</if>
+            <if test="payType != null  and payType != ''"> and pay_type = #{payType}</if>
+        </where>
+    </select>
+    
+    <select id="selectVolunteerPaymentRecordsByVolunteerPaymentRecordsId" parameterType="Long" resultMap="VolunteerPaymentRecordsResult">
+        <include refid="selectVolunteerPaymentRecordsVo"/>
+        where volunteer_payment_records_id = #{volunteerPaymentRecordsId}
+    </select>
+
+    <insert id="insertVolunteerPaymentRecords" parameterType="VolunteerPaymentRecords">
+        insert into l_volunteer_payment_records
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="volunteerPaymentRecordsId != null">volunteer_payment_records_id,</if>
+            <if test="paymentOrderNumber != null and paymentOrderNumber != ''">payment_order_number,</if>
+            <if test="isVerified != null and isVerified != ''">is_verified,</if>
+            <if test="paymentStatus != null and paymentStatus != ''">payment_status,</if>
+            <if test="paymentTime != null">payment_time,</if>
+            <if test="failedPaymentAttempts != null">failed_payment_attempts,</if>
+            <if test="failedPaymentReason != null">failed_payment_reason,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="deleted != null and deleted != ''">deleted,</if>
+            <if test="totalPaymentAmount != null">total_payment_amount,</if>
+            <if test="actualPaymentAmount != null">actual_payment_amount,</if>
+            <if test="successfulPaymentAmount != null">successful_payment_amount,</if>
+            <if test="failedPaymentAmount != null">failed_payment_amount,</if>
+            <if test="jsonContent != null">json_content,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="payType != null">pay_type,</if>
+            <if test="createBy != null">create_by,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="volunteerPaymentRecordsId != null">#{volunteerPaymentRecordsId},</if>
+            <if test="paymentOrderNumber != null and paymentOrderNumber != ''">#{paymentOrderNumber},</if>
+            <if test="isVerified != null and isVerified != ''">#{isVerified},</if>
+            <if test="paymentStatus != null and paymentStatus != ''">#{paymentStatus},</if>
+            <if test="paymentTime != null">#{paymentTime},</if>
+            <if test="failedPaymentAttempts != null">#{failedPaymentAttempts},</if>
+            <if test="failedPaymentReason != null">#{failedPaymentReason},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="deleted != null and deleted != ''">#{deleted},</if>
+            <if test="totalPaymentAmount != null">#{totalPaymentAmount},</if>
+            <if test="actualPaymentAmount != null">#{actualPaymentAmount},</if>
+            <if test="successfulPaymentAmount != null">#{successfulPaymentAmount},</if>
+            <if test="failedPaymentAmount != null">#{failedPaymentAmount},</if>
+            <if test="jsonContent != null">#{jsonContent},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="payType != null">#{payType},</if>
+            <if test="createBy != null">#{createBy},</if>
+         </trim>
+    </insert>
+
+    <update id="updateVolunteerPaymentRecords" parameterType="VolunteerPaymentRecords">
+        update l_volunteer_payment_records
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="paymentOrderNumber != null and paymentOrderNumber != ''">payment_order_number = #{paymentOrderNumber},</if>
+            <if test="isVerified != null and isVerified != ''">is_verified = #{isVerified},</if>
+            <if test="paymentStatus != null and paymentStatus != ''">payment_status = #{paymentStatus},</if>
+            <if test="paymentTime != null">payment_time = #{paymentTime},</if>
+            <if test="failedPaymentAttempts != null">failed_payment_attempts = #{failedPaymentAttempts},</if>
+            <if test="failedPaymentReason != null">failed_payment_reason = #{failedPaymentReason},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="deleted != null and deleted != ''">deleted = #{deleted},</if>
+            <if test="totalPaymentAmount != null">total_payment_amount = #{totalPaymentAmount},</if>
+            <if test="actualPaymentAmount != null">actual_payment_amount = #{actualPaymentAmount},</if>
+            <if test="successfulPaymentAmount != null">successful_payment_amount = #{successfulPaymentAmount},</if>
+            <if test="failedPaymentAmount != null">failed_payment_amount = #{failedPaymentAmount},</if>
+            <if test="jsonContent != null">json_content = #{jsonContent},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="payType != null">pay_type = #{payType},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+        </trim>
+        where volunteer_payment_records_id = #{volunteerPaymentRecordsId}
+    </update>
+
+    <delete id="deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsId" parameterType="Long">
+        delete from l_volunteer_payment_records where volunteer_payment_records_id = #{volunteerPaymentRecordsId}
+    </delete>
+
+    <delete id="deleteVolunteerPaymentRecordsByVolunteerPaymentRecordsIds" parameterType="String">
+        delete from l_volunteer_payment_records where volunteer_payment_records_id in 
+        <foreach item="volunteerPaymentRecordsId" collection="array" open="(" separator="," close=")">
+            #{volunteerPaymentRecordsId}
+        </foreach>
+    </delete>
+</mapper>

+ 220 - 0
leromro-core/src/main/resources/mapper/core/VolunteerTakeRecordMapper.xml

@@ -0,0 +1,220 @@
+<?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.leromro.core.mapper.VolunteerTakeRecordMapper">
+    
+    <resultMap type="VolunteerTakeRecord" id="VolunteerTakeRecordResult">
+        <result property="volunteerTakeRecordId"    column="volunteer_take_record_id"    />
+        <result property="takeSn"    column="take_sn"    />
+        <result property="volunteerAccountId"    column="volunteer_account_id"    />
+        <result property="volunteerUserId"    column="volunteer_user_id"    />
+        <result property="takeAmount"    column="take_amount"    />
+        <result property="shoudAmount"    column="shoud_amount"    />
+        <result property="taxAmount"    column="tax_amount"    />
+        <result property="receiveAmount"    column="receive_amount"    />
+        <result property="payType"    column="pay_type"    />
+        <result property="bankName"    column="bank_name"    />
+        <result property="bankCode"    column="bank_code"    />
+        <result property="bankCardUser"    column="bank_card_user"    />
+        <result property="bankCardSn"    column="bank_card_sn"    />
+        <result property="bankCardAddress"    column="bank_card_address"    />
+        <result property="payTime"    column="pay_time"    />
+        <result property="payNote"    column="pay_note"    />
+        <result property="payName"    column="pay_name"    />
+        <result property="isPay"    column="is_pay"    />
+        <result property="paySn"    column="pay_sn"    />
+        <result property="payVoucherPics"    column="pay_voucher_pics"    />
+        <result property="deleted"    column="deleted"    />
+        <result property="alipayAccountNo"    column="alipay_account_no"    />
+        <result property="alipayName"    column="alipay_name"    />
+        <result property="paymentRecordId"    column="payment_record_id"    />
+        <result property="lastTime"    column="last_time"    />
+        <result property="payCode"    column="pay_code"    />
+        <result property="appTime"    column="app_time"    />
+        <result property="appStatus"    column="app_status"    />
+        <result property="appUserId"    column="app_user_id"    />
+        <result property="appUserName"    column="app_user_name"    />
+        <result property="rejectReason"    column="reject_reason"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="remark"    column="remark"    />
+    </resultMap>
+
+    <sql id="selectVolunteerTakeRecordVo">
+        select * from l_volunteer_take_record
+    </sql>
+
+    <select id="selectVolunteerTakeRecordList" parameterType="VolunteerTakeRecord" resultMap="VolunteerTakeRecordResult">
+        <include refid="selectVolunteerTakeRecordVo"/>
+        <where>  
+            <if test="takeSn != null  and takeSn != ''"> and take_sn = #{takeSn}</if>
+            <if test="volunteerAccountId != null "> and volunteer_account_id = #{volunteerAccountId}</if>
+            <if test="volunteerUserId != null "> and volunteer_user_id = #{volunteerUserId}</if>
+            <if test="takeAmount != null "> and take_amount = #{takeAmount}</if>
+            <if test="shoudAmount != null "> and shoud_amount = #{shoudAmount}</if>
+            <if test="taxAmount != null "> and tax_amount = #{taxAmount}</if>
+            <if test="receiveAmount != null "> and receive_amount = #{receiveAmount}</if>
+            <if test="payType != null  and payType != ''"> and pay_type = #{payType}</if>
+            <if test="bankName != null  and bankName != ''"> and bank_name like concat('%', #{bankName}, '%')</if>
+            <if test="bankCode != null  and bankCode != ''"> and bank_code = #{bankCode}</if>
+            <if test="bankCardUser != null  and bankCardUser != ''"> and bank_card_user = #{bankCardUser}</if>
+            <if test="bankCardSn != null  and bankCardSn != ''"> and bank_card_sn = #{bankCardSn}</if>
+            <if test="bankCardAddress != null  and bankCardAddress != ''"> and bank_card_address = #{bankCardAddress}</if>
+            <if test="payTime != null "> and pay_time = #{payTime}</if>
+            <if test="payNote != null  and payNote != ''"> and pay_note = #{payNote}</if>
+            <if test="payName != null  and payName != ''"> and pay_name like concat('%', #{payName}, '%')</if>
+            <if test="isPay != null  and isPay != ''"> and is_pay = #{isPay}</if>
+            <if test="paySn != null  and paySn != ''"> and pay_sn = #{paySn}</if>
+            <if test="payVoucherPics != null  and payVoucherPics != ''"> and pay_voucher_pics = #{payVoucherPics}</if>
+            <if test="deleted != null  and deleted != ''"> and deleted = #{deleted}</if>
+            <if test="alipayAccountNo != null  and alipayAccountNo != ''"> and alipay_account_no = #{alipayAccountNo}</if>
+            <if test="alipayName != null  and alipayName != ''"> and alipay_name like concat('%', #{alipayName}, '%')</if>
+            <if test="paymentRecordId != null "> and payment_record_id = #{paymentRecordId}</if>
+            <if test="lastTime != null "> and last_time = #{lastTime}</if>
+            <if test="payCode != null  and payCode != ''"> and pay_code = #{payCode}</if>
+            <if test="rejectReason != null  and rejectReason != ''"> and reject_reason = #{rejectReason}</if>
+            <if test="appStatus != null and appStatus != ''">and app_status = #{appStatus}</if>
+        </where>
+    </select>
+    
+    <select id="selectVolunteerTakeRecordByVolunteerTakeRecordId" parameterType="Long" resultMap="VolunteerTakeRecordResult">
+        <include refid="selectVolunteerTakeRecordVo"/>
+        where volunteer_take_record_id = #{volunteerTakeRecordId}
+    </select>
+
+    <insert id="insertVolunteerTakeRecord" parameterType="VolunteerTakeRecord">
+        insert into l_volunteer_take_record
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="volunteerTakeRecordId != null">volunteer_take_record_id,</if>
+            <if test="takeSn != null">take_sn,</if>
+            <if test="volunteerAccountId != null">volunteer_account_id,</if>
+            <if test="volunteerUserId != null">volunteer_user_id,</if>
+            <if test="takeAmount != null">take_amount,</if>
+            <if test="shoudAmount != null">shoud_amount,</if>
+            <if test="taxAmount != null">tax_amount,</if>
+            <if test="receiveAmount != null">receive_amount,</if>
+            <if test="payType != null">pay_type,</if>
+            <if test="bankName != null">bank_name,</if>
+            <if test="bankCode != null">bank_code,</if>
+            <if test="bankCardUser != null">bank_card_user,</if>
+            <if test="bankCardSn != null">bank_card_sn,</if>
+            <if test="bankCardAddress != null">bank_card_address,</if>
+            <if test="payTime != null">pay_time,</if>
+            <if test="payNote != null">pay_note,</if>
+            <if test="payName != null">pay_name,</if>
+            <if test="isPay != null">is_pay,</if>
+            <if test="paySn != null">pay_sn,</if>
+            <if test="payVoucherPics != null">pay_voucher_pics,</if>
+            <if test="deleted != null">deleted,</if>
+            <if test="alipayAccountNo != null">alipay_account_no,</if>
+            <if test="alipayName != null">alipay_name,</if>
+            <if test="paymentRecordId != null">payment_record_id,</if>
+            <if test="lastTime != null">last_time,</if>
+            <if test="payCode != null">pay_code,</if>
+            <if test="checkTime != null">check_time,</if>
+            <if test="checkStatus != null">check_status,</if>
+            <if test="checkUserId != null">check_user_id,</if>
+            <if test="checkUserName != null">check_user_name,</if>
+            <if test="rejectReason != null">reject_reason,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="remark != null">remark,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="volunteerTakeRecordId != null">#{volunteerTakeRecordId},</if>
+            <if test="takeSn != null">#{takeSn},</if>
+            <if test="volunteerAccountId != null">#{volunteerAccountId},</if>
+            <if test="volunteerUserId != null">#{volunteerUserId},</if>
+            <if test="takeAmount != null">#{takeAmount},</if>
+            <if test="shoudAmount != null">#{shoudAmount},</if>
+            <if test="taxAmount != null">#{taxAmount},</if>
+            <if test="receiveAmount != null">#{receiveAmount},</if>
+            <if test="payType != null">#{payType},</if>
+            <if test="bankName != null">#{bankName},</if>
+            <if test="bankCode != null">#{bankCode},</if>
+            <if test="bankCardUser != null">#{bankCardUser},</if>
+            <if test="bankCardSn != null">#{bankCardSn},</if>
+            <if test="bankCardAddress != null">#{bankCardAddress},</if>
+            <if test="payTime != null">#{payTime},</if>
+            <if test="payNote != null">#{payNote},</if>
+            <if test="payName != null">#{payName},</if>
+            <if test="isPay != null">#{isPay},</if>
+            <if test="paySn != null">#{paySn},</if>
+            <if test="payVoucherPics != null">#{payVoucherPics},</if>
+            <if test="deleted != null">#{deleted},</if>
+            <if test="alipayAccountNo != null">#{alipayAccountNo},</if>
+            <if test="alipayName != null">#{alipayName},</if>
+            <if test="paymentRecordId != null">#{paymentRecordId},</if>
+            <if test="lastTime != null">#{lastTime},</if>
+            <if test="payCode != null">#{payCode},</if>
+            <if test="checkTime != null">#{checkTime},</if>
+            <if test="checkStatus != null">#{checkStatus},</if>
+            <if test="checkUserId != null">#{checkUserId},</if>
+            <if test="checkUserName != null">#{checkUserName},</if>
+            <if test="rejectReason != null">#{rejectReason},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="remark != null">#{remark},</if>
+         </trim>
+    </insert>
+
+    <update id="updateVolunteerTakeRecord" parameterType="VolunteerTakeRecord">
+        update l_volunteer_take_record
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="takeSn != null">take_sn = #{takeSn},</if>
+            <if test="volunteerAccountId != null">volunteer_account_id = #{volunteerAccountId},</if>
+            <if test="volunteerUserId != null">volunteer_user_id = #{volunteerUserId},</if>
+            <if test="takeAmount != null">take_amount = #{takeAmount},</if>
+            <if test="shoudAmount != null">shoud_amount = #{shoudAmount},</if>
+            <if test="taxAmount != null">tax_amount = #{taxAmount},</if>
+            <if test="receiveAmount != null">receive_amount = #{receiveAmount},</if>
+            <if test="payType != null">pay_type = #{payType},</if>
+            <if test="bankName != null">bank_name = #{bankName},</if>
+            <if test="bankCode != null">bank_code = #{bankCode},</if>
+            <if test="bankCardUser != null">bank_card_user = #{bankCardUser},</if>
+            <if test="bankCardSn != null">bank_card_sn = #{bankCardSn},</if>
+            <if test="bankCardAddress != null">bank_card_address = #{bankCardAddress},</if>
+            <if test="payTime != null">pay_time = #{payTime},</if>
+            <if test="payNote != null">pay_note = #{payNote},</if>
+            <if test="payName != null">pay_name = #{payName},</if>
+            <if test="isPay != null">is_pay = #{isPay},</if>
+            <if test="paySn != null">pay_sn = #{paySn},</if>
+            <if test="payVoucherPics != null">pay_voucher_pics = #{payVoucherPics},</if>
+            <if test="deleted != null">deleted = #{deleted},</if>
+            <if test="alipayAccountNo != null">alipay_account_no = #{alipayAccountNo},</if>
+            <if test="alipayName != null">alipay_name = #{alipayName},</if>
+            <if test="paymentRecordId != null">payment_record_id = #{paymentRecordId},</if>
+            <if test="lastTime != null">last_time = #{lastTime},</if>
+            <if test="payCode != null">pay_code = #{payCode},</if>
+            <if test="checkTime != null">check_time = #{checkTime},</if>
+            <if test="checkStatus != null">check_status = #{checkStatus},</if>
+            <if test="checkUserId != null">check_user_id = #{checkUserId},</if>
+            <if test="checkUserName != null">check_user_name = #{checkUserName},</if>
+            <if test="rejectReason != null">reject_reason = #{rejectReason},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where volunteer_take_record_id = #{volunteerTakeRecordId}
+    </update>
+
+    <delete id="deleteVolunteerTakeRecordByVolunteerTakeRecordId" parameterType="Long">
+        delete from l_volunteer_take_record where volunteer_take_record_id = #{volunteerTakeRecordId}
+    </delete>
+
+    <delete id="deleteVolunteerTakeRecordByVolunteerTakeRecordIds" parameterType="String">
+        delete from l_volunteer_take_record where volunteer_take_record_id in 
+        <foreach item="volunteerTakeRecordId" collection="array" open="(" separator="," close=")">
+            #{volunteerTakeRecordId}
+        </foreach>
+    </delete>
+</mapper>

+ 63 - 0
leromro-framework/src/main/java/com/leromro/framework/config/AliConfig.java

@@ -0,0 +1,63 @@
+package com.leromro.framework.config;
+
+import cn.hutool.core.io.FileUtil;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.AlipayConfig;
+import com.alipay.api.CertAlipayRequest;
+import com.alipay.api.DefaultAlipayClient;
+import java.io.File;
+import java.io.InputStream;
+
+import com.leromro.common.utils.MyImgUtil;
+import com.leromro.framework.config.properties.AliAdminPayProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AliConfig {
+
+    @Autowired
+    private AliAdminPayProperties adminPayProperties;
+
+
+    @Bean
+    public CertAlipayRequest aliTakePayClient() {
+        CertAlipayRequest payConfig = new CertAlipayRequest();
+        payConfig.setAppId(this.adminPayProperties.getAppId());
+        payConfig.setPrivateKey(this.adminPayProperties.getPrivateKey());
+        payConfig.setServerUrl(this.adminPayProperties.getServerUrl());
+        payConfig.setSignType(this.adminPayProperties.getSignType());
+        payConfig.setFormat("json");
+        payConfig.setCharset("UTF8");
+        try {
+            InputStream certPathStream = getClass().getResourceAsStream("/appCertPublicKey_2021004131699060.crt");
+            if (certPathStream != null) {
+                File certPath = FileUtil.writeBytes(MyImgUtil.readInputStream(certPathStream), "appCertPublicKey_2021004131699060.crt");
+                payConfig.setCertPath(certPath.getPath());
+                InputStream alipayPublicCertStream = getClass().getResourceAsStream("/alipayCertPublicKey_RSA2.crt");
+                File alipayPublicFile = FileUtil.writeBytes(MyImgUtil.readInputStream(alipayPublicCertStream), "alipayCertPublicKey_RSA2.crt");
+                payConfig.setAlipayPublicCertPath(alipayPublicFile.getPath());
+                InputStream rootCertStream = getClass().getResourceAsStream("/alipayRootCert.crt");
+                File rootCertFile = FileUtil.writeBytes(MyImgUtil.readInputStream(rootCertStream), "alipayRootCert.crt");
+                payConfig.setRootCertPath(rootCertFile.getPath());
+            }
+//            // 使用绝对路径指定证书文件
+//            String certBasePath = "D:\\pay\\alipay\\";
+//
+//            payConfig.setCertPath(certBasePath + "appCertPublicKey_2021004131699060.crt");
+//            payConfig.setAlipayPublicCertPath(certBasePath + "alipayCertPublicKey_RSA2.crt");
+//            payConfig.setRootCertPath(certBasePath + "alipayRootCert.crt");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return payConfig;
+    }
+
+    @Bean
+    public AlipayClient aliPayService(@Qualifier("aliTakePayClient") CertAlipayRequest payConfig) throws AlipayApiException {
+        return new DefaultAlipayClient(payConfig);
+    }
+}

+ 3 - 1
leromro-framework/src/main/java/com/leromro/framework/config/ConstantsConfig.java

@@ -7,7 +7,9 @@ public enum ConstantsConfig {
 //    短信通知
     SMS_TEMPLATE_TYPE_PHONE_CODE("sms_template_type_phone_code", "SMS_484025217"),
 //    志愿者审批通知
-    SMS_TEMPLATE_TYPE_VOLUNTEER_RESULT("sms_template_type_volunteer_result","SMS_485465604");
+    SMS_TEMPLATE_TYPE_VOLUNTEER_RESULT("sms_template_type_volunteer_result","SMS_485465604"),
+    //志愿者提现成功通知
+    SMS_TEMPLATE_TYPE_VOLUNTEER_WITGDRAW("sms_template_type_volunteer_withdraw","SMS_486195063");
 
 
     private final String KEY;

+ 20 - 0
leromro-framework/src/main/java/com/leromro/framework/config/properties/AliAdminPayProperties.java

@@ -0,0 +1,20 @@
+package com.leromro.framework.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+@Data
+@ConfigurationProperties(prefix = "aliyun.admpay")
+@Configuration
+/* loaded from: jc-common-1.0.0.jar:org/jjr/jc/common/config/aliyun/AliAdminPayProperties.class */
+public class AliAdminPayProperties {
+    private String appId;
+    private String privateKey;
+    private String alipayPublicKey;
+    private String serverUrl;
+    private String signType;
+    private String certPath;
+    private String alipayPublicCertPath;
+    private String rootCertPath;
+
+}

+ 7 - 0
pom.xml

@@ -305,6 +305,13 @@
                 <version>3.16.3</version>
             </dependency>
 
+            <!-- 支付宝支付 -->
+            <dependency>
+                <groupId>com.alipay.sdk</groupId>
+                <artifactId>alipay-sdk-java</artifactId>
+                <version>4.35.37.ALL</version>
+            </dependency>
+
 
 
         </dependencies>