ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ExchangeDispatchFallbackFactory.java
@@ -61,6 +61,11 @@ public R<Boolean> refuseChangeDispatch(String id) { return R.fail(cause.getMessage()); } @Override public void changeReason(String id, String reason) { } }; } } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/OrderFallbackFactory.java
@@ -12,6 +12,7 @@ import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.Date; import java.util.List; /** @@ -247,6 +248,11 @@ } @Override public R<Boolean> updateArrivalTime(String orderId, Date arriveTime) { return null; } @Override public R<Boolean> changeOrderState(String orderId, Integer state) { return R.fail(cause.getMessage()); } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ExchangeDispatchClient.java
@@ -108,4 +108,6 @@ @GetMapping(value = "changeDispatch/refuseChangeDispatch") R<Boolean> refuseChangeDispatch(@RequestParam("id") String id); @GetMapping(value = "changeDispatch/changeReason") void changeReason(@RequestParam("id")String id,@RequestParam("reason") String reason); } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java
@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestParam; import java.math.BigDecimal; import java.util.Date; import java.util.List; /** @@ -425,5 +426,6 @@ R<String> oldData(@RequestParam("index") Integer index, @RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize); @GetMapping(value = "/order/updateArrivalTime") R<Boolean> updateArrivalTime(@RequestParam("orderId")String orderId,@RequestParam("arriveTime")Date arriveTime); } ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -146,6 +146,7 @@ * 订单记录excel模板名称 */ public static final String EXCEL_ORDER_FILE_NAME = "订单记录"; public static final String EXCEL_ORDER_FILE_NAME1 = "加盟商余额记录"; /** * 用户编号生成前缀 ruoyi-service/ruoyi-admin/pom.xml
@@ -19,6 +19,12 @@ <dependencies> <dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-java</artifactId> <version>0.2.12</version> </dependency> <dependency> <groupId>org.openeuler</groupId> <artifactId>bgmprovider</artifactId> <version>1.0.4</version> ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/config/WeChatConfig.java
New file @@ -0,0 +1,121 @@ package com.ruoyi.admin.config; import javax.annotation.PostConstruct; import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; import com.wechat.pay.java.service.refund.RefundService; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.core.notification.NotificationConfig; import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.service.payments.h5.H5Service; import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.payments.nativepay.NativePayService; import lombok.Getter; import java.security.PrivateKey; /** * @desc: 微信config * @author: shy * @date: 2024/4/9 10:06 */ @Configuration @Getter public class WeChatConfig { /** * 商户号 */ @Value("${wx.mchId}") public String merchantId; /** * 商户API私钥路径 */ @Value("${wx.privateKeyPath}") public String privateKeyPath; /** * 商户证书序列号 */ @Value("${wx.merchantSerialNumber}") public String merchantSerialNumber; /** * 商户APIV3密钥 */ @Value("${wx.apiV3Key}") public String apiV3Key; /** * AppId */ @Value("${wx.appId}") public String appId; private Config config; @Getter private PrivateKey privateKey; @PostConstruct public void initConfig() { // 使用自动更新平台证书的RSA配置 // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错 config = new RSAAutoCertificateConfig.Builder() .merchantId(merchantId) .privateKeyFromPath(privateKeyPath) .merchantSerialNumber(merchantSerialNumber) .apiV3Key(apiV3Key) .build(); } @Primary @Bean() public H5Service h5Service() { return new H5Service.Builder() .config(config) .build(); } @Primary @Bean() public JsapiService jsapiService() { return new JsapiService.Builder() .config(config) .build(); } @Primary @Bean() public NativePayService nativePayService() { return new NativePayService.Builder() .config(config) .build(); } @Primary @Bean() public RefundService refundService() { return new RefundService.Builder() .config(config) .build(); } @Primary @Bean public NotificationParser notificationParser() { return new NotificationParser((NotificationConfig) config); } @Primary @Bean public PrivateKeySigner privateKeySigner() { return new PrivateKeySigner(merchantSerialNumber, privateKey); } } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/ChangeDispatchController.java
@@ -60,10 +60,11 @@ @ApiImplicitParam(value = "师傅名称", name = "workerName", dataType = "String"), @ApiImplicitParam(value = "订单编号", name = "orderNumber", dataType = "String"), @ApiImplicitParam(value = "下单用户名称", name = "userName", dataType = "String"), @ApiImplicitParam(value = "地址", name = "reservationAddress", dataType = "String"), @ApiImplicitParam(value = "页码", name = "pageNum", dataType = "Integer", required = true), @ApiImplicitParam(value = "每页条数", name = "pageSize", dataType = "Integer", required = true) }) public R<Page<ChangeDispatch>> queryPageList(String workerName, String orderNumber, String userName, public R<Page<ChangeDispatch>> queryPageList(String workerName, String orderNumber, String userName,String reservationAddress, @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { LoginUser loginUser = tokenService.getLoginUser(); @@ -75,6 +76,7 @@ changeDispatchRequest.setWorkerName(workerName); changeDispatchRequest.setOrderNumber(orderNumber); changeDispatchRequest.setUserName(userName); changeDispatchRequest.setReservationAddress(reservationAddress); changeDispatchRequest.setPageNum(pageNum); changeDispatchRequest.setPageSize(pageSize); changeDispatchRequest.setCityList(cityList); ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/FranchiseeController.java
@@ -1,29 +1,69 @@ package com.ruoyi.admin.controller; import cn.hutool.http.HttpException; import com.alibaba.excel.EasyExcelFactory; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.metadata.WriteSheet; import com.alipay.api.AlipayApiException; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.admin.config.WeChatConfig; import com.ruoyi.admin.entity.*; import com.ruoyi.admin.service.*; import com.ruoyi.admin.utils.MD5AndKL; import com.ruoyi.admin.utils.WeChatUtil; import com.ruoyi.admin.vo.InfoDto; import com.ruoyi.admin.vo.MoneyRecentQuery; import com.ruoyi.admin.vo.RencentBalance; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.GlobalException; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.common.security.service.TokenService; import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; import com.wechat.pay.java.core.exception.MalformedMessageException; import com.wechat.pay.java.core.exception.ServiceException; import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.service.partnerpayments.app.model.Transaction; import com.wechat.pay.java.service.payments.jsapi.model.Amount; import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.payments.jsapi.model.Payer; import com. wechat. pay. java. service. payments. jsapi. model. PrepayRequest; import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse; import com.wechat.pay.java.service.payments.nativepay.NativePayService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.Getter; import org.apache.commons.codec.CharEncoding; import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.math.BigDecimal; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.SecureRandom; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** * <p> @@ -50,6 +90,338 @@ private MasterWorkerService masterWorkerService; @Resource private SiteService siteService; @Resource private JsapiService jsapiService; @Resource private WeChatConfig weChatConfig; @Resource private PrivateKeySigner privateKeySigner; @Resource private TFranchiseeBalanceChangeService balanceChangeService; private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final Random RANDOM = new SecureRandom(); @ApiOperation(value = "加盟商列表余额", tags = {"后台2.0-加盟商列表余额"}) @PostMapping(value = "/recent/money") public R<RencentBalance> recentmoney() { BigDecimal balance = new BigDecimal(0); List<Franchisee> list = franchiseeService.lambdaQuery().list(); for (Franchisee franchisee : list) { balance = balance.add(franchisee.getBalance()); } //充值的金额 BigDecimal balance1 = new BigDecimal(0); List<TFranchiseeBalanceChange> list1 = balanceChangeService.lambdaQuery().eq(TFranchiseeBalanceChange::getType, 1).list(); for (TFranchiseeBalanceChange franchiseeBalanceChange : list1) { balance1 = balance1.add(franchiseeBalanceChange.getAmount()); } //扣除的金额 BigDecimal balance2 = new BigDecimal(0); List<TFranchiseeBalanceChange> list2 = balanceChangeService.lambdaQuery().eq(TFranchiseeBalanceChange::getType, 2).list(); for (TFranchiseeBalanceChange franchiseeBalanceChange : list1) { balance2 = balance2.add(franchiseeBalanceChange.getAmount()); } RencentBalance balance3 = new RencentBalance(); balance3.setBalance1(balance); balance3.setBalance2(balance1); balance3.setBalance3(balance2); return R.ok(balance3); } @ApiOperation(value = "扣款记录及充值记录", tags = {"后台2.0-统一充值扣款列表","师傅段2.0-统一充值扣款列表"}) @PostMapping(value = "/recent/money/list") public R<Page<TFranchiseeBalanceChange>> recentmoneylist(@RequestBody MoneyRecentQuery moneyRecentQuery) { Page<TFranchiseeBalanceChange> page = balanceChangeService.lambdaQuery().eq(moneyRecentQuery.getType() != null, TFranchiseeBalanceChange::getType, moneyRecentQuery.getType()) .eq(moneyRecentQuery.getFranchId() != null, TFranchiseeBalanceChange::getFranchiseeId, moneyRecentQuery.getFranchId()) .eq(moneyRecentQuery.getFranchName() != null && !"".equals(moneyRecentQuery.getFranchName()), TFranchiseeBalanceChange::getFranchiseeName, moneyRecentQuery.getFranchName()) .ge(moneyRecentQuery.getDate1() != null, TFranchiseeBalanceChange::getCreateTime, moneyRecentQuery.getDate1()) .le(moneyRecentQuery.getDate2() != null, TFranchiseeBalanceChange::getCreateTime, moneyRecentQuery.getDate2()) .page(Page.of(moneyRecentQuery.getPageNum(), moneyRecentQuery.getPageSize())); for (TFranchiseeBalanceChange record : page.getRecords()) { Franchisee franchisee = franchiseeService.getById(record.getFranchiseeId()); String siteIds = franchisee.getSiteIds(); String cityCode = franchisee.getCityCode(); List<Region> list = regionService.lambdaQuery().in(Region::getCode, cityCode.split(",")).list(); List<Site> list1 = siteService.lambdaQuery().in(Site::getId, siteIds.split(",")).list(); record.setList(list); record.setList1(list1); record.setFranchiseeName(franchisee.getName()); } return R.ok(page); } @ApiOperation(value = "导出", tags = {"后台2.0-统一充值扣款列表"}) @PostMapping(value = "/recent/money/list/export") public R<Page<TFranchiseeBalanceChange>> export(@RequestBody MoneyRecentQuery moneyRecentQuery, HttpServletResponse response) { List<TFranchiseeBalanceChange> page = balanceChangeService.lambdaQuery().eq(moneyRecentQuery.getType() != null, TFranchiseeBalanceChange::getType, moneyRecentQuery.getType()) .eq(moneyRecentQuery.getFranchId() != null, TFranchiseeBalanceChange::getFranchiseeId, moneyRecentQuery.getFranchId()) .eq(moneyRecentQuery.getFranchName() != null && !"".equals(moneyRecentQuery.getFranchName()), TFranchiseeBalanceChange::getFranchiseeName, moneyRecentQuery.getFranchName()) .ge(moneyRecentQuery.getDate1() != null, TFranchiseeBalanceChange::getCreateTime, moneyRecentQuery.getDate1()) .le(moneyRecentQuery.getDate2() != null, TFranchiseeBalanceChange::getCreateTime, moneyRecentQuery.getDate2()) .list(); try { response.setCharacterEncoding(Constants.UTF8); response.setContentType("application/vnd.ms-excel"); response.setHeader("Access-Control-Expose-Headers", "Content-disposition"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(Constants.EXCEL_ORDER_FILE_NAME, CharEncoding.UTF_8) + ".xlsx"); } catch (UnsupportedEncodingException e) { return R.fail("excel导出失败!"); } try { // excel模板封装 ExcelWriterBuilder excelWriterBuilder = EasyExcelFactory.write(response.getOutputStream()); InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/" + Constants.EXCEL_ORDER_FILE_NAME1 + ".xlsx"); // 自动释放资源 try (ExcelWriter excelWriter = excelWriterBuilder.withTemplate(stream).build()) { WriteSheet writeSheet = EasyExcelFactory.writerSheet().build(); excelWriter.fill(page, writeSheet); excelWriter.finish(); } catch (Exception e) { return R.fail("excel导出失败!"); } } catch (IOException e) { return R.fail("excel导出失败!"); } return R.ok(); } @ApiOperation(value = "扣余额", tags = {"后台2.0-加盟商列表余额"}) @PostMapping(value = "/recent/money/consume") public R<Page<TFranchiseeBalanceChange>> consume(@RequestBody TFranchiseeBalanceChange franchiseeBalanceChange) { Franchisee byId = franchiseeService.getById(franchiseeBalanceChange.getFranchiseeId()); franchiseeBalanceChange.setFranchiseeName(byId.getName()); balanceChangeService.save(franchiseeBalanceChange); byId.setBalance(byId.getBalance().subtract(franchiseeBalanceChange.getAmount())); franchiseeService.updateById(byId); return R.ok(); } @Getter private PrivateKey privateKey; @ApiOperation(value = "js支付", tags = {"2.0-支付"}) @GetMapping(value = "/js/wxPay") public R jsPay(@RequestParam String openId,@RequestParam BigDecimal money,@RequestParam Integer userId) { SysUser byId1 = sysUserService.getById(userId); this.privateKey = PemUtil.loadPrivateKey(getPrivateKeyStream()); this.privateKeySigner = new PrivateKeySigner(weChatConfig.merchantSerialNumber, privateKey); String code = generateTradeNumber(); int i = money.multiply(BigDecimal.valueOf(100)).intValue(); Franchisee byId = franchiseeService.getById(byId1.getFranchiseeId()); PrepayRequest prepayRequest = new PrepayRequest(); prepayRequest.setAppid(weChatConfig.appId); prepayRequest.setMchid(weChatConfig.merchantId); prepayRequest.setDescription("加盟商充值"); prepayRequest.setOutTradeNo(code); prepayRequest.setNotifyUrl("http://www.zhipingwang.com.cn:9090/admin/franchisee/callBack"); Amount amount = new Amount(); amount.setTotal(i); prepayRequest.setAmount(amount); Payer payer = new Payer(); payer.setOpenid(openId); prepayRequest.setPayer(payer); PrepayResponse prepay = jsapiService.prepay(prepayRequest); String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); String packageStr = "prepay_id=" + prepay.getPrepayId(); String prepay_id = prepay.getPrepayId(); //重新进行签名后返回给前端 Map<String, Object> map2 = new HashMap<>(); map2.put("appid", weChatConfig.getAppId()); map2.put("noncestr", code); map2.put("package", "Sign=WXPay"); map2.put("partnerid", weChatConfig.getMerchantId()); map2.put("prepayid", prepay_id); map2.put("timestamp", timeStamp); // String s1 = this.weixinSignature(map2); String signStr = Stream.of(weChatConfig.getAppId(), timeStamp, code, packageStr).collect(Collectors.joining("\n", "", "\n")); String packageSign = privateKeySigner.sign(signStr.getBytes(StandardCharsets.UTF_8)).getSign(); map2.put("sign", packageSign); System.err.println(map2); TFranchiseeBalanceChange tFranchiseeBalanceChange = new TFranchiseeBalanceChange(); tFranchiseeBalanceChange.setAmount(money); tFranchiseeBalanceChange.setIs_pay(0); tFranchiseeBalanceChange.setFranchiseeName(byId.getName()); tFranchiseeBalanceChange.setFranchiseeId(String.valueOf(byId.getId())); tFranchiseeBalanceChange.setType(2); tFranchiseeBalanceChange.setCode(code); balanceChangeService.save(tFranchiseeBalanceChange); return R.ok(map2); } public InputStream getPrivateKeyStream() { // 需要证书释放 byte[] certData; // InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(this.privateKeyPath); InputStream certStream = null; try { certStream = new FileInputStream(weChatConfig.privateKeyPath); certData = IOUtils.toByteArray(certStream); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("私钥文件未找到"); }finally { if(null != certStream){ try { certStream.close(); } catch (IOException e) { } } } return new ByteArrayInputStream(certData); } @Resource private TokenService tokenService; @Resource private NativePayService nativePayService; @ApiOperation(value = "扫码支付",tags = {"后台2.0-加盟商列表余额"}) @PostMapping(value = "/code/buy") public R buy(@RequestParam BigDecimal money) throws AlipayApiException { Long userid = tokenService.getLoginUser().getUserid(); SysUser byId1 = sysUserService.getById(userid); Franchisee byId = franchiseeService.getById(byId1.getFranchiseeId()); String code = generateTradeNumber(); int i = money.multiply(BigDecimal.valueOf(100)).intValue(); com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest prepayRequest = new com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest(); prepayRequest.setAppid(weChatConfig.appId); prepayRequest.setMchid(weChatConfig.merchantId); prepayRequest.setOutTradeNo(code); prepayRequest.setDescription("购买资料"); prepayRequest.setNotifyUrl("http://www.zhipingwang.com.cn:9090/admin/franchisee/callBack"); com.wechat.pay.java.service.payments.nativepay.model.Amount amount = new com.wechat.pay.java.service.payments.nativepay.model.Amount(); amount.setTotal(i); prepayRequest.setAmount(amount); // 调用下单方法,得到应答 com.wechat.pay.java.service.partnerpayments.app.model.PrepayResponse response; try { com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse prepay = nativePayService.prepay(prepayRequest); //预支付成功,创建预支付订单 TFranchiseeBalanceChange tFranchiseeBalanceChange = new TFranchiseeBalanceChange(); tFranchiseeBalanceChange.setAmount(money); tFranchiseeBalanceChange.setIs_pay(0); tFranchiseeBalanceChange.setFranchiseeName(byId.getName()); tFranchiseeBalanceChange.setFranchiseeId(String.valueOf(userid)); tFranchiseeBalanceChange.setType(2); tFranchiseeBalanceChange.setCode(code); balanceChangeService.save(tFranchiseeBalanceChange); return R.ok(prepay.getCodeUrl()); } catch (HttpException e) { // 发送HTTP请求失败 // log.error("发送HTTP请求失败: {}", e.getHttpRequest()); } catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500 // log.error("服务返回状态异常: {}", e.getResponseBody()); } catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败 // log.error("返回体类型不合法: {}", e.getMessage()); } catch (Exception e) { // log.error("预下单异常: {}", e.getMessage()); } return null; } @Resource private NotificationParser notificationParser; @ApiOperation(value = "支付回调",tags = {"微信支付回调"}) @RequestMapping (value = "/callBack") @Transactional public R payNotify(HttpServletRequest request) throws Exception{ System.err.println("======回调开始"); Transaction transaction; transaction = notificationParser.parse(WeChatUtil.handleNodifyRequestParam(request), Transaction.class); if (transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) { //将记录变为已支付 TFranchiseeBalanceChange one = balanceChangeService.lambdaQuery().eq(TFranchiseeBalanceChange::getCode, transaction.getOutTradeNo()).one(); if (one.getIs_pay()==0) { //将加盟商的余额增加 Franchisee byId = franchiseeService.getById(one.getFranchiseeId()); byId.setBalance(byId.getBalance().add(one.getAmount())); franchiseeService.updateById(byId); one.setIs_pay(1); balanceChangeService.updateById(one); } } return R.ok(null,"SUCCESS"); } public static String generateTradeNumber() { // 定义订单号前缀 // 当前年月日 LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String currentTimeStr =now.format(formatter); // 获取当前时间戳 long timestamp = System.currentTimeMillis(); // 构造订单号 return currentTimeStr + timestamp; } private String weixinSignature(Map<String, Object> map){ try { Set<Map.Entry<String, Object>> entries = map.entrySet(); List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { return (o1.getKey()).toString().compareTo(o2.getKey()); } }); // 构造签名键值对的格式 StringBuilder sb = new StringBuilder(); for (Map.Entry<String, Object> item : infoIds) { if (item.getKey() != null || item.getKey() != "") { String key = item.getKey(); Object val = item.getValue(); if (!(val == "" || val == null)) { sb.append(key + "=" + val + "&"); } } } sb.append("key=" + "TA2npSNWmS0GcB0tFFRWA94rm1M0iSFs"); String sign = MD5AndKL.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); //注:MD5签名方式 return sign; } catch (Exception e) { e.printStackTrace(); } return null; } public static String generateNonceStr() { char[] nonceChars = new char[32]; for (int index = 0; index < nonceChars.length; ++index) { nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); } return new String(nonceChars); } /** * 加盟商信息分页列表 @@ -103,8 +475,13 @@ @ApiImplicitParam(value = "加盟商信息id", name = "id", dataType = "Integer", required = true) }) public R<Franchisee> detail(@RequestParam("id") Integer id) { return R.ok(franchiseeService.lambdaQuery() .eq(Franchisee::getId, id).eq(Franchisee::getIsDelete, 0).one()); Franchisee one = franchiseeService.lambdaQuery() .eq(Franchisee::getId, id).eq(Franchisee::getIsDelete, 0).one(); List<Site> list = siteService.lambdaQuery().in(Site::getId, one.getSiteIds().split(",")).list(); //用 , 拼接 one.setSiteStr(list.stream().map(Site::getSiteName).collect(Collectors.joining(","))); return R.ok(one); } /** @@ -121,6 +498,53 @@ return R.ok(Arrays.stream(franchisee.getCityCode().split(",")).collect(Collectors.toList())); } @ApiOperation(value = "主页信息", tags = {"2.0师傅端"}) @GetMapping(value = "/info") public R<InfoDto> info() { Long userid = tokenService.getLoginUser().getUserid(); SysUser byId = sysUserService.getById(userid); Franchisee franchisee = franchiseeService.lambdaQuery() .eq(Franchisee::getId, byId.getFranchiseeId()).eq(Franchisee::getIsDelete, 0).one(); String siteIds = franchisee.getSiteIds(); String cityCode = franchisee.getCityCode(); List<Region> list = regionService.lambdaQuery().in(Region::getCode, cityCode.split(",")).list(); List<Site> list1 = siteService.lambdaQuery().in(Site::getId, siteIds.split(",")).list(); InfoDto infoDto = new InfoDto(); infoDto.setList(list); infoDto.setList1(list1); infoDto.setFranchisee(franchisee); return R.ok(infoDto); } @ApiOperation(value = "主页信息", tags = {"2.0师傅端"}) @GetMapping(value = "/info1") public R<InfoDto> info1(Integer id) { Franchisee franchisee = franchiseeService.lambdaQuery() .eq(Franchisee::getId, id).eq(Franchisee::getIsDelete, 0).one(); String siteIds = franchisee.getSiteIds(); String cityCode = franchisee.getCityCode(); List<Region> list = regionService.lambdaQuery().in(Region::getCode, cityCode.split(",")).list(); List<Site> list1 = siteService.lambdaQuery().in(Site::getId, siteIds.split(",")).list(); InfoDto infoDto = new InfoDto(); infoDto.setList(list); infoDto.setList1(list1); infoDto.setFranchisee(franchisee); return R.ok(infoDto); } @ApiOperation(value = "当前余额", tags = {"后台2.0-加盟商列表余额"}) @GetMapping(value = "/rencentBalance") public R<Franchisee> rencentBalance() { Long userid = tokenService.getLoginUser().getUserid(); SysUser byId = sysUserService.getById(userid); Franchisee franchisee = franchiseeService.lambdaQuery() .eq(Franchisee::getId, byId.getFranchiseeId()).eq(Franchisee::getIsDelete, 0).one(); return R.ok(franchisee); } @GetMapping(value = "/getWorkPic") public R<String> getWorkPic(@RequestParam("id") Integer id) { MasterWorker byId = masterWorkerService.getById(id); ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/OrderController.java
@@ -404,12 +404,7 @@ @RequiresPermissions("order_reassignment") @ApiOperation(value = "订单列表-订单派单/改派", tags = {"后台-订单管理"}) @PostMapping(value = "/reassignment") @ApiImplicitParams({ @ApiImplicitParam(value = "操作类型(1:订单派单;2:订单改派)", name = "type", dataType = "Integer", required = true), @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "Integer", required = true), @ApiImplicitParam(value = "服务人员id", name = "workerId", dataType = "Integer", required = true), @ApiImplicitParam(value = "改派原因", name = "applyReason", dataType = "String") }) @Transactional(rollbackFor = Exception.class) public R<String> reassignment(@RequestBody OrderReasinDto orderReasinDto) { // String[] split = orderIds.split(","); @@ -426,11 +421,22 @@ if (Constants.TWO.equals(orderId.getType())) { if (order.getState().equals(Constants.SIX) || order.getState().equals(Constants.THREE)) { orderClient.updateState(order.getId(), Constants.ONE); //如果是待改派,将上门时间设置为最新的,并且更新再投原因 if (order.getState().equals(Constants.SIX)){ dispatchClient.changeReason(order.getId(), orderReasinDto.getReason()); orderClient.updateArrivalTime(order.getId(),orderReasinDto.getArriveTime()); } } // 订单状态为 待完工时,需要更改状态 待上门且清空师傅到达预约点时间 if (order.getState().equals(Constants.TWO)) { orderClient.updateStateAndArrivalTime(orderId.getOrderId(), Constants.ONE); } // 生成改派信息 // ChangeDispatch changeDispatch = new ChangeDispatch(); // changeDispatch.setWorkerId(item.getServerId()); ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/controller/SiteController.java
@@ -55,7 +55,7 @@ public R<IPage<Site>> queryPageList(@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { return R.ok(siteService.lambdaQuery().orderByDesc(Site::getCreateTime) .eq(Site::getIsDelete, 0) .eq(Site::getIsDelete, 0).orderByDesc(Site::getSort) .page(Page.of(pageNum, pageSize))); } @@ -85,7 +85,7 @@ return R.ok(siteService.lambdaQuery().orderByDesc(Site::getCreateTime).in(siteIds.length>0, Site::getId, siteIds).like(siteName!=null&&siteName!="", Site::getSiteName, siteName) .eq(Site::getIsDelete, 0) .eq(Site::getIsDelete, 0).orderByDesc(Site::getSort) .list()); } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Franchisee.java
@@ -9,9 +9,11 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import org.apache.poi.hpsf.Decimal; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.math.BigDecimal; /** * <p> @@ -89,6 +91,9 @@ @ApiModelProperty("管辖城市二维数组") @TableField("site_ids") private String siteIds; @ApiModelProperty("余额") @TableField("balance") private BigDecimal balance; @TableField(exist = false) private String siteStr; } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/Site.java
@@ -26,6 +26,9 @@ @TableId(value = "id",type = IdType.AUTO) private Integer id; @ApiModelProperty("排序") @TableField("sort") private Integer sort; @ApiModelProperty("站点名称") @TableField("site_name") ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/entity/TFranchiseeBalanceChange.java
New file @@ -0,0 +1,91 @@ package com.ruoyi.admin.entity; import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; /** * <p> * * </p> * * @author luodangjia * @since 2024-11-02 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_franchisee_balance_change") @ApiModel(value="TFranchiseeBalanceChange对象", description="") public class TFranchiseeBalanceChange implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty(value = "扣除金额") @TableField("amount") private BigDecimal amount; @TableField("region_name") private String regionName; @TableField("region_id") private Integer regionId; @TableField("createBy") private String createBy; @TableField("pics") private String pics; @TableField("site_id") private Integer siteId; @TableField("is_pay") private Integer is_pay; @TableField("franchisee_name") private String franchiseeName; @TableField("franchisee_id") private String franchiseeId; @TableField("code") private String code; @TableField("remark") private String remark; @TableField("updateBy") private String updateBy; @TableField("createTime") private LocalDateTime createTime; @TableField("updateTime") private LocalDateTime updateTime; @ApiModelProperty(value = "1扣款2充值") @TableField("type") private Integer type; @ApiModelProperty(value = "是否删除 0未删除;1已删除") @TableField("is_delete") @TableLogic private Integer isDelete; @TableField(exist = false) private String payStr = "微信支付"; @TableField(exist = false) private List<Region> list; @TableField(exist = false) private List<Site> list1; @TableField(exist = false) private List<Site> franchiseName; } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/mapper/TFranchiseeBalanceChangeMapper.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.admin.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.admin.entity.TFranchiseeBalanceChange; /** * <p> * Mapper 接口 * </p> * * @author luodangjia * @since 2024-11-02 */ public interface TFranchiseeBalanceChangeMapper extends BaseMapper<TFranchiseeBalanceChange> { } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/TFranchiseeBalanceChangeService.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.admin.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.admin.entity.TFranchiseeBalanceChange; /** * <p> * 服务类 * </p> * * @author luodangjia * @since 2024-11-02 */ public interface TFranchiseeBalanceChangeService extends IService<TFranchiseeBalanceChange> { } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/service/impl/TFranchiseeBalanceChangeServiceImpl.java
New file @@ -0,0 +1,21 @@ package com.ruoyi.admin.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.admin.entity.TFranchiseeBalanceChange; import com.ruoyi.admin.mapper.TFranchiseeBalanceChangeMapper; import com.ruoyi.admin.service.TFranchiseeBalanceChangeService; import org.springframework.stereotype.Service; /** * <p> * 服务实现类 * </p> * * @author luodangjia * @since 2024-11-02 */ @Service public class TFranchiseeBalanceChangeServiceImpl extends ServiceImpl<TFranchiseeBalanceChangeMapper, TFranchiseeBalanceChange> implements TFranchiseeBalanceChangeService { } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/MD5AndKL.java
New file @@ -0,0 +1,112 @@ package com.ruoyi.admin.utils; import java.security.MessageDigest; public class MD5AndKL { /** * MD5加码。32位 * * @param inStr * @return */ public static String MD5(String inStr) { MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { throw new RuntimeException(e.toString()); } byte[] md5Bytes = md5.digest(inStr.getBytes()); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) { hexValue.append("0"); } hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } /** * 可逆的加密算法 * * @param inStr * @return */ public static String KL(String inStr) { char[] a = inStr.toCharArray(); for (int i = 0; i < a.length; i++) { a[i] = (char) (a[i] ^ 't'); } String s = new String(a); return s; } /** * 加密后解密 * * @param inStr * @return */ public static String JM(String inStr) { char[] a = inStr.toCharArray(); for (int i = 0; i < a.length; i++) { a[i] = (char) (a[i] ^ 't'); } String k = new String(a); return k; } private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } public static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); if (charsetname == null || "".equals(charsetname)){ resultString = byteArrayToHexString(md.digest(resultString.getBytes())); }else{ resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } } catch (Exception exception) { exception.printStackTrace(); } return resultString; } private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; public static void main(String args[]) { System.out.println("MD5后再加密:" + KL(MD5("123456"))); System.out.println(MD5("123456")); // System.out.println("加密:" + KL(MD5("123456"))); // s = KL(s); // System.out.println("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055")); // System.out.println("解密:" + JM(KL(s))); // System.out.println("解密为MD5后的:" + KL(KL(MD5(s)))); // System.out.println(JM("5d62957bb57d3e49dcf48a0df064be4c")); // System.out.println(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321"))); } } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/WeChatUtil.java
New file @@ -0,0 +1,128 @@ package com.ruoyi.admin.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.security.PrivateKey; import java.security.SecureRandom; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Random; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import com.wechat.pay.java.core.cipher.RSASigner; import com.wechat.pay.java.core.cipher.SignatureResult; import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.core.util.NonceUtil; import com.wechat.pay.java.core.util.PemUtil; /** * @desc: 微信工具类 * @author: shy * @date: 2024/4/8 16:10 */ public class WeChatUtil { private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final Random RANDOM = new SecureRandom(); /** * 生成订单号 * * @param * @return String * @author shy * @date 2024/4/8 16:15 */ public static String generateTradeNumber() { // 定义订单号前缀 // 当前年月日 LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String currentTimeStr =now.format(formatter); // 获取当前时间戳 long timestamp = System.currentTimeMillis(); // 构造订单号 return currentTimeStr + timestamp; } /** * 获取随机字符串 Nonce Str * * @param * @return String * @author shy * @date 2024/4/16 17:07 */ public static String generateNonceStr() { return NonceUtil.createNonce(32); } /** * 获取当前时间戳,单位秒 * @param * @return long * @author shy * @date 2024/4/16 17:10 */ public static long getCurrentTimestamp() { return System.currentTimeMillis() / 1000; } public static String getSign(String signatureStr, String privateKeyPath, String merchantSerialNumber) { PrivateKey privateKey = PemUtil.loadPrivateKeyFromPath(privateKeyPath); RSASigner rsaSigner = new RSASigner(merchantSerialNumber, privateKey); SignatureResult signatureResult = rsaSigner.sign(signatureStr); return signatureResult.getSign(); } /** * 构造 RequestParam * * @param request * @return RequestParam * @author shy * @date 2024/4/9 11:16 */ public static RequestParam handleNodifyRequestParam(HttpServletRequest request) throws IOException { // 请求头Wechatpay-Signature String signature = request.getHeader("Wechatpay-Signature"); // 请求头Wechatpay-nonce String nonce = request.getHeader("Wechatpay-Nonce"); // 请求头Wechatpay-Timestamp String timestamp = request.getHeader("Wechatpay-Timestamp"); // 微信支付证书序列号 String serial = request.getHeader("Wechatpay-Serial"); // 签名方式 String signType = request.getHeader("Wechatpay-Signature-Type"); // 构造 RequestParam return new RequestParam.Builder().serialNumber(serial).nonce(nonce).signature(signature).timestamp(timestamp).signType(signType).body(getRequestBody(request)).build(); } public static String getRequestBody(HttpServletRequest request) throws IOException { ServletInputStream stream; BufferedReader reader = null; StringBuilder sb = new StringBuilder(); try { stream = request.getInputStream(); // 获取响应 reader = new BufferedReader(new InputStreamReader(stream)); String line; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { throw new IOException("读取返回支付接口数据流出现异常!"); } finally { if (reader != null) { reader.close(); } } return sb.toString(); } } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/utils/WechatPaySignature.java
New file @@ -0,0 +1,36 @@ package com.ruoyi.admin.utils; import org.apache.commons.codec.digest.DigestUtils; import java.util.Map; import java.util.TreeMap; public class WechatPaySignature { // 模拟的签名生成函数,实际应用中应使用微信提供的签名算法 public static String generateSignature(Map<String, String> parameters, String apiKey) { // 这里应该使用微信官方提供的签名算法来生成sign // 示例仅为说明,实际中不要直接如此使用 StringBuilder toSign = new StringBuilder(); for (Map.Entry<String, String> entry : parameters.entrySet()) { toSign.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } toSign.append("key=").append(apiKey); // 对字符串进行MD5或其他加密 return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); } public static void main(String[] args) { Map<String, String> params = new TreeMap<>(); params.put("appId", "wx98563d0ec9cf21c8"); params.put("timeStamp", "1392689076"); params.put("nonceStr", "e614eka7e99d027403216e8dfa37ddc2"); params.put("package", "prepay_id=wx01181404626776e879e6764f2760370000"); params.put("signType", "MD5"); String apiKey = "TA2npSNWmS0GcB0tFFRWA94rm1M0iSFs"; // 你的API密钥 String paySign = generateSignature(params, apiKey); System.out.println("paySign: " + paySign); } } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/InfoDto.java
New file @@ -0,0 +1,15 @@ package com.ruoyi.admin.vo; import com.ruoyi.admin.entity.Franchisee; import com.ruoyi.admin.entity.Region; import com.ruoyi.admin.entity.Site; import lombok.Data; import java.util.List; @Data public class InfoDto { Franchisee franchisee; List<Region> list ; List<Site> list1 ; } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/MoneyRecentQuery.java
New file @@ -0,0 +1,25 @@ package com.ruoyi.admin.vo; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; @Data public class MoneyRecentQuery { @ApiModelProperty("加盟商id") private Integer franchId; @ApiModelProperty("加盟商名字,查询用") private Integer franchName; @ApiModelProperty("1扣款2充值") private Integer type; @ApiModelProperty("扣款时间1") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime date1; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @ApiModelProperty("扣款时间2") private LocalDateTime date2; private Integer pageNum; private Integer pageSize; } ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/OrderReasinDto.java
@@ -2,9 +2,11 @@ import lombok.Data; import java.util.Date; import java.util.List; @Data public class OrderReasinDto { Integer workerId; List<ReassinDto> reassinDtos; } String reason; Date arriveTime;} ruoyi-service/ruoyi-admin/src/main/java/com/ruoyi/admin/vo/RencentBalance.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.admin.vo; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.apache.poi.hpsf.Decimal; import java.math.BigDecimal; @Data public class RencentBalance { private BigDecimal balance1; private BigDecimal balance2; private BigDecimal balance3; } ruoyi-service/ruoyi-admin/src/main/resources/template/加盟商余额记录.xlsx
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChangeDispatchController.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.GlobalException; import com.ruoyi.common.security.annotation.RequiresPermissions; @@ -195,6 +196,14 @@ return R.ok(update && orderService.updateById(order)); } @GetMapping(value = "/changeReason") public void changeReason(@RequestParam("id")String id,@RequestParam("reason") String reason) { ChangeDispatch one = changeDispatchService.lambdaQuery().eq(ChangeDispatch::getOrderId, id).orderByDesc(BaseEntity::getCreateTime).last("limit 1").one(); one.setState(1); one.setApplyReason(reason); changeDispatchService.updateById(one); } /** * 根据id批量删除订单改派 * ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -516,6 +516,13 @@ return R.ok(!list.isEmpty()); } @GetMapping(value = "/updateArrivalTime") public R<Boolean> updateArrivalTime(@RequestParam("orderId")String orderId,@RequestParam("arriveTime")Date arriveTime) { Order byId = orderService.getById(orderId); byId.setArriveTime(arriveTime); return R.ok(); } /** * 回收订单统计 * ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/request/ChangeDispatchRequest.java
@@ -15,6 +15,7 @@ private String workerName; private String orderNumber; private String reservationAddress; private String userName; ruoyi-service/ruoyi-order/src/main/resources/mapper/order/ChangeDispatchMapper.xml
@@ -19,10 +19,13 @@ <result column="user_id" property="userId"/> <result column="user_name" property="userName"/> <result column="orderTime" property="orderTime"/> <result column="reservation_name" property="reservationName"/> <result column="reservation_phone" property="reservationPhone"/> <result column="reservation_address" property="reservationAddress"/> </resultMap> <select id="queryPageList" resultMap="BaseResultMap"> select c.*, o.createTime as orderTime,o.type as type select c.*, o.createTime as orderTime,o.type as type,o.reservation_name,o.reservation_phone,o.reservation_address from sys_change_dispatch c left join t_order o on c.order_id = o.id <where> @@ -36,6 +39,9 @@ <if test="data.userName != null and data.userName != ''"> and c.user_name like concat('%', #{data.userName}, '%') </if> <if test="data.reservationAddress != null and data.reservationAddress != ''"> and o.reservationAddress like concat('%', #{data.reservationAddress}, '%') </if> <if test="data.cityList != null and data.cityList.size() != 0"> and o.city_code in <foreach collection="data.cityList" item="city" open="(" separator="," close=")"> ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OrderController.java
@@ -390,7 +390,7 @@ String nowStr = now.format(formatter); redisService.setCacheObject("MARK:"+workerId+":"+nowStr,longitude + "," + latitude); redisService.setCacheObject("MARK:"+workerId+":"+nowStr,longitude + "," + latitude, 10L, TimeUnit.MINUTES); String cacheObject = redisService.getCacheObject("MARK:" + workerId + ":" + formattedTime); if (cacheObject!=null){ @@ -430,7 +430,7 @@ System.err.println("-----当前距离"+distance); //如果超出一定范围,存入Mark文件 if (distance<50){ redisService.setCacheObject("TIME:"+workerId,LocalDateTime.now()); redisService.setCacheObject("TIME:"+workerId,LocalDateTime.now(), 10L, TimeUnit.MINUTES); marker(longitude,latitude); } } ruoyi-service/ruoyi-worker/src/main/java/com/ruoyi/worker/controller/OssController.java
@@ -12,7 +12,9 @@ import io.swagger.annotations.ApiOperation; import lombok.Synchronized; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -30,6 +32,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.concurrent.CompletableFuture; /** @@ -71,42 +74,125 @@ return R.ok(tencentCosUtil.upLoadFile(file)); } // @PostMapping(value = "/pic", produces = "application/json;charset=UTF-8") // @ApiOperation(value = "文件上传加水印", tags = "师傅端-文件上传") // @ApiImplicitParams({ // @ApiImplicitParam(value = "文件", name = "file", dataType = "MultipartFile", required = true) // }) // public R<String> pic(@RequestParam("file") MultipartFile file,String longitude, // String latitude) { //// Result<String> address = GaoDeMapUtil.getAddress(longitude, latitude); ////// return R.fail(); //// //// // 获取当前时间 //// //// LocalDateTime date = LocalDateTime.now(); //// //// // 设置日期格式 //// //// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); //// //// // 通过format调用转换的方法 //// //// String dateWatermark = formatter.format(date); ////// System.err.println("==========="+LocalDateTime.now()); //// log.error("==========="+LocalDateTime.now()); //// //// MultipartFile watermarkFile = FileImageWatermarkUtils.markWithContent(file,dateWatermark,address.getDatas()); ////// System.err.println("==========="+LocalDateTime.now()); //// log.error("==========="+LocalDateTime.now()); //// //// //// String url = tencentCosUtil.upLoadFile(watermarkFile); ////// String url = tencentCosUtil.upLoadFile(file); //// log.error("==========="+LocalDateTime.now()); //// return R.ok(url); // // // // 参数校验 // if (file == null || file.isEmpty()) { // return R.fail("文件不能为空"); // } // if (longitude == null || longitude.isEmpty() || latitude == null || latitude.isEmpty()) { // return R.fail("经纬度参数不能为空"); // } // // try { // // 获取地址信息 // Result<String> addressResult = GaoDeMapUtil.getAddress(longitude, latitude); // if (addressResult == null || addressResult.getDatas() == null) { // return R.fail("无法获取地址信息"); // } // // // 获取当前时间 // LocalDateTime date = LocalDateTime.now(); // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // String dateWatermark = formatter.format(date); // log.info("===========" + dateWatermark); // // // 给图片加水印 // MultipartFile watermarkFile = FileImageWatermarkUtils.markWithContent(file, dateWatermark, addressResult.getDatas()); // log.info("水印添加成功"); // // // 上传到腾讯云COS // String url = tencentCosUtil.upLoadFile(watermarkFile); // log.info("文件上传成功,URL: " + url); // // return R.ok(url); // } catch (Exception e) { // log.error("文件上传加水印失败: ", e); // return R.fail("文件上传加水印失败: " + e.getMessage()); // } // } @Autowired private ThreadPoolTaskExecutor taskExecutor; @PostMapping(value = "/pic", produces = "application/json;charset=UTF-8") @ApiOperation(value = "文件上传加水印", tags = "师傅端-文件上传") @ApiImplicitParams({ @ApiImplicitParam(value = "文件", name = "file", dataType = "MultipartFile", required = true) }) @Synchronized public R<String> pic(@RequestParam("file") MultipartFile file,String longitude,String address, String latitude) { // Result<String> address = GaoDeMapUtil.getAddress(longitude, latitude); // return R.fail(); public CompletableFuture<R<String>> pic(@RequestParam("file") MultipartFile file, String longitude, String latitude) { // 参数校验 if (file == null || file.isEmpty()) { return CompletableFuture.completedFuture(R.fail("文件不能为空")); } if (longitude == null || longitude.isEmpty() || latitude == null || latitude.isEmpty()) { return CompletableFuture.completedFuture(R.fail("经纬度参数不能为空")); } // 获取当前时间 return CompletableFuture.supplyAsync(() -> { try { // 获取地址信息 Result<String> addressResult = GaoDeMapUtil.getAddress(longitude, latitude); if (addressResult == null || addressResult.getDatas() == null) { return R.fail("无法获取地址信息"); } LocalDateTime date = LocalDateTime.now(); // 获取当前时间 LocalDateTime date = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String dateWatermark = formatter.format(date); log.info("===========" + dateWatermark); // 设置日期格式 // 给图片加水印 MultipartFile watermarkFile = FileImageWatermarkUtils.markWithContent(file, dateWatermark, addressResult.getDatas()); log.info("水印添加成功"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 上传到腾讯云COS String url = tencentCosUtil.upLoadFile(watermarkFile); log.info("文件上传成功,URL: " + url); // 通过format调用转换的方法 String dateWatermark = formatter.format(date); // System.err.println("==========="+LocalDateTime.now()); log.error("==========="+LocalDateTime.now()); MultipartFile watermarkFile = FileImageWatermarkUtils.markWithContent(file,dateWatermark,address); // System.err.println("==========="+LocalDateTime.now()); log.error("==========="+LocalDateTime.now()); String url = tencentCosUtil.upLoadFile(watermarkFile); // String url = tencentCosUtil.upLoadFile(file); log.error("==========="+LocalDateTime.now()); return R.ok(url); return R.ok(url); } catch (Exception e) { log.error("文件上传加水印失败: ", e); return R.fail("文件上传加水印失败: " + e.getMessage()); } }, taskExecutor); } }