已添加9个文件
已删除1个文件
已修改27个文件
已重命名1个文件
| | |
| | | |
| | | |
| | | -- ============================================================ |
| | | -- 2026/04/20 åæ·ä¸å¸æºå¢å æ¯ä»å®å®åå§ååæ®µ |
| | | -- ============================================================ |
| | | ALTER TABLE `shop_info` ADD COLUMN `ALI_NAME` VARCHAR(50) DEFAULT NULL COMMENT 'æ¯ä»å®å®åå§å' AFTER `ALI_ACCOUNT`; |
| | | ALTER TABLE `driver_info` ADD COLUMN `ALI_ACCOUNT` VARCHAR(100) DEFAULT NULL COMMENT 'æ¯ä»å®æç°è´¦æ·' AFTER `LATITUDE`; |
| | | ALTER TABLE `driver_info` ADD COLUMN `ALI_NAME` VARCHAR(50) DEFAULT NULL COMMENT 'æ¯ä»å®å®åå§å' AFTER `ALI_ACCOUNT`; |
| | | |
| | | |
| | | -- ============================================================ |
| | | -- 2026/04/20 订å鿬¾è®°å½è¡¨å¢å 鿬¾ç¶æå段 |
| | | -- ============================================================ |
| | | ALTER TABLE `orders_refund` ADD COLUMN `STATUS` INT DEFAULT 0 COMMENT '鿬¾ç¶æï¼0=鿬¾ä¸ï¼1=鿬¾æåï¼2=鿬¾å¤±è´¥' AFTER `REFUND_REMARK`; |
| | | |
| | | |
| | | -- ============================================================ |
| | | -- 2026/04/20 订å表å¢å ç©å级å«å段 |
| | | -- ============================================================ |
| | | ALTER TABLE `orders` ADD COLUMN `GOOD_LEVEL` INT DEFAULT NULL COMMENT 'ç©å级å«ï¼category主é®ï¼type=3ï¼' AFTER `GOOD_TYPE`; |
| | |
| | | package com.doumee.biz.system.impl; |
| | | |
| | | import com.doumee.biz.system.AreasBiz; |
| | | import com.doumee.dao.business.AreasMapper; |
| | | import com.doumee.dao.business.model.Areas; |
| | | import com.doumee.service.business.AreasService; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | |
| | | public class AreasBizImpl implements AreasBiz { |
| | | |
| | | @Autowired |
| | | private AreasService areasService; |
| | | private AreasMapper areasMapper; |
| | | |
| | | @Override |
| | | public Areas resolveArea(Integer areaId) { |
| | | if (areaId == null) { |
| | | return null; |
| | | } |
| | | // cacheData ä¸å·²ä¸ºæ¯æ¡åºå¿è®°å½å¡«å
äº provinceId/provinceName/cityId/cityName |
| | | return areasService.findById(areaId); |
| | | |
| | | return areasMapper.selectJoinOne(Areas.class,new MPJLambdaWrapper<Areas>() |
| | | .selectAll(Areas.class) |
| | | .select(" a1.id ",Areas::getCityId) |
| | | .select(" a1.name ",Areas::getCityName) |
| | | .select(" a2.id ",Areas::getProvinceId) |
| | | .select(" a2.name ",Areas::getProvinceName) |
| | | .leftJoin("areas a1 on a1.id = t.PARENT_ID") |
| | | .leftJoin("areas a2 on a2.id = a1.PARENT_ID") |
| | | .eq(Areas::getId, areaId) |
| | | ); |
| | | |
| | | // if (areaId == null) { |
| | | // return null; |
| | | // } |
| | | // // cacheData ä¸å·²ä¸ºæ¯æ¡åºå¿è®°å½å¡«å
äº provinceId/provinceName/cityId/cityName |
| | | // return areasMapper.selectById(areaId); |
| | | } |
| | | |
| | | } |
| | |
| | | package com.doumee.config.alipay; |
| | | |
| | | import com.alipay.v3.ApiException; |
| | | import com.alipay.v3.ApiClient; |
| | | import com.alipay.v3.util.model.AlipayConfig; |
| | | import com.alipay.v3.ApiException; |
| | | import com.alipay.v3.Configuration; |
| | | import com.alipay.v3.api.AlipayFundTransUniApi; |
| | | import com.alipay.v3.model.*; |
| | | import com.alipay.v3.util.model.AlipayConfig; |
| | | import com.doumee.config.mybatis.SpringUtils; |
| | | import com.doumee.core.constants.ResponseStatus; |
| | | import com.doumee.core.exception.BusinessException; |
| | | import com.doumee.dao.dto.AlipayTransferDTO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ¯ä»å®åç¬è½¬è´¦å·¥å
·ç±» |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Slf4j |
| | | @org.springframework.context.annotation.Configuration |
| | | public class AlipayFundTransUniTransfer { |
| | | |
| | | public static void main(String[] args) throws ApiException { |
| | | // åå§åSDK |
| | | ApiClient defaultClient = Configuration.getDefaultApiClient(); |
| | | // åå§åalipayåæ°ï¼å
¨å±è®¾ç½®ä¸æ¬¡ï¼ |
| | | defaultClient.setAlipayConfig(getAlipayConfig()); |
| | | // æé 请æ±åæ°ä»¥è°ç¨æ¥å£ |
| | | AlipayFundTransUniApi api = new AlipayFundTransUniApi(); |
| | | AlipayFundTransUniTransferModel data = new AlipayFundTransUniTransferModel(); |
| | | // 设置åå®¶ä¾§å¯ä¸è®¢åå· |
| | | data.setOutBizNo("202606300001"); |
| | | // è®¾ç½®è®¢åæ»éé¢ |
| | | data.setTransAmount("1"); |
| | | // 设置æè¿°ç¹å®çä¸å¡åºæ¯ |
| | | data.setBizScene("DIRECT_TRANSFER"); |
| | | // 设置ä¸å¡äº§åç |
| | | data.setProductCode("TRANS_ACCOUNT_NO_PWD"); |
| | | // 设置转账ä¸å¡çæ é¢ |
| | | data.setOrderTitle("201905代å"); |
| | | // è®¾ç½®åæ¯ä»å®ä¸å¡åå· |
| | | data.setOriginalOrderId("20190620110075000006640000063056"); |
| | | // è®¾ç½®æ¶æ¬¾æ¹ä¿¡æ¯ |
| | | Participant payeeInfo = new Participant(); |
| | | payeeInfo.setIdentity("15345690849"); |
| | | payeeInfo.setName("æ±è"); |
| | | payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); |
| | | data.setPayeeInfo(payeeInfo); |
| | | // 设置ä¸å¡å¤æ³¨ |
| | | data.setRemark("201905代å"); |
| | | // è®¾ç½®è½¬è´¦åºæ¯åç§° |
| | | data.setTransferSceneName("佣鿥é
¬"); |
| | | private static AlipayConfig alipayConfig; |
| | | |
| | | // è®¾ç½®è½¬è´¦åºæ¯ä¸æ¥ä¿¡æ¯ |
| | | List<TransferSceneReportInfo> transferSceneReportInfos = new ArrayList<TransferSceneReportInfo>(); |
| | | TransferSceneReportInfo transferSceneReportInfos0 = new TransferSceneReportInfo(); |
| | | transferSceneReportInfos0.setInfoType("佣鿥é
¬è¯´æ"); |
| | | transferSceneReportInfos0.setInfoContent("3æå®¶æ¿æå¡æ¥é
¬"); |
| | | transferSceneReportInfos.add(transferSceneReportInfos0); |
| | | data.setTransferSceneReportInfos(transferSceneReportInfos); |
| | | @Autowired |
| | | private AlipayProperties alipayProperties; |
| | | |
| | | // 设置转账ä¸å¡è¯·æ±çæ©å±åæ° |
| | | data.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}"); |
| | | public static AlipayFundTransUniTransfer me() { |
| | | return SpringUtils.get().getBean(AlipayFundTransUniTransfer.class); |
| | | } |
| | | |
| | | /* // 设置ç¾åä¿¡æ¯ |
| | | SignData signData = new SignData(); |
| | | signData.setOriSign("EqHFP0z4a9iaQ1ep=="); |
| | | signData.setPartnerId("ç¾åè¢«æææ¹æ¯ä»å®è´¦å·ID"); |
| | | signData.setOriAppId("2021000185629012"); |
| | | signData.setOriOutBizNo("åæ·è®¢åå·"); |
| | | signData.setOriSignType("RSA2"); |
| | | signData.setOriCharSet("UTF-8"); |
| | | data.setSignData(signData); |
| | | */ |
| | | @PostConstruct |
| | | void init() { |
| | | this.loadAlipayConfig(); |
| | | } |
| | | |
| | | public void loadAlipayConfig() { |
| | | try { |
| | | AlipayFundTransUniTransferResponseModel response = api.transfer(data); |
| | | } catch (ApiException e) { |
| | | AlipayFundTransUniTransferDefaultResponse errorObject = (AlipayFundTransUniTransferDefaultResponse) e.getErrorObject(); |
| | | System.out.println("è°ç¨å¤±è´¥:" + errorObject); |
| | | AlipayConfig config = new AlipayConfig(); |
| | | config.setServerUrl("https://openapi.alipay.com"); |
| | | config.setAppId(StringUtils.trimToNull(alipayProperties.getAppId())); |
| | | config.setPrivateKey(StringUtils.trimToNull(alipayProperties.getPrivateKey())); |
| | | config.setAppCertPath(StringUtils.trimToNull(alipayProperties.getAppCertPath())); |
| | | config.setAlipayPublicCertPath(StringUtils.trimToNull(alipayProperties.getAlipayPublicCertPath())); |
| | | config.setRootCertPath(StringUtils.trimToNull(alipayProperties.getRootCertPath())); |
| | | alipayConfig = config; |
| | | log.info("æ¯ä»å®é
ç½®åå§åæå, appId={}", config.getAppId()); |
| | | } catch (Exception e) { |
| | | log.error("æ¯ä»å®é
ç½®åå§å失败: {}", e.getMessage(), e); |
| | | } |
| | | } |
| | | |
| | | private static AlipayConfig getAlipayConfig() { |
| | | AlipayConfig alipayConfig = new AlipayConfig(); |
| | | alipayConfig.setServerUrl("https://openapi.alipay.com"); |
| | | alipayConfig.setAppId("2021006147660139"); |
| | | String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEeqqkZztBHfK+vpyBi6ejgDTHZuZ3yiuXds+lRBbMo/g24F5trH+oLHW0gMhSxihFfQBBIpVBXDsPQK4ZkhDWTaOBktnU1UMRoOEiaaZU6EiWy10ePFUmpdXpkCQEp7rc88OwI90p58S3+L+Ckak60WqNwJBdB5YGBaUunryBA78U4zW1KNY7JvoRnZDcFMQiczikwUzhO7EAi0yVrVpsVsc9s87mcS4uOJKx4qb2E83r9RJ1z30db+cIIZRiLP2oNZBLYzgKpOouE+uIgxhQzlh6cOASNZQulXuUjoT/+Y9w4njfl4TmKIXWcJFKIMc6kMiux9tTncpp0TqRwk1tAgMBAAECggEALkSYtJheusnbpRFr95G0i2sggqh3s1PXihZ/dXKgT9Z5GCsj8X3Cng7CNRxykBN73kk+axhCv56Bhej8Vqcv8ddcnqG/TEBgR+Fzws/QTIRau6/uILWic7RvuE2qPbJl7aw1s9/uL/UVPSGFr7CvgltYVUM4e7/Sk1529JCK4XJfoXP5tKJ3OaXssvaFnCKEU8IGQkjRG+lUZJhAHVtClGHtgrhevgRhy2zre5wp2qSa8d/MqrPruSYS02hn9b5Nl6i2PlUS6dGlJ4lrxYTG22ukYYoxAPNPS7gnvmveXonWP7b5tPhKRpZjnoySojz3WECUlhz/v8wM1cDrpq+GQQKBgQDsc7y2rlx4f77a7ORfb5/qWHCOJs1cIzggj0kJ7TgFGe71kbCQ5nywD/Fe5V9OwbW+DCxOME+SrrHeiK4axWiu5si/1JlurJoxNy+4k4ywk3ZA3Nv2aBhlPqfkwDhJ0z7Mgsq2c/YgnVddmSvKZoC39wA77ovks4GDxaBOt8N7PQKBgQDUuPGgzkwcgb60UdaxfMbacrPsW26vDxaE4ceuXo2m8KDiCIqkF2y9r6AdWMTgGGSJwOsk7+FP+21VdRivCg9HcOLWngveUc6xDIuqKHVpemMo3SdCF4Wqf96rRc3VOBr5cfIdWxeorZf5umMyKnIAjAFETOOrK7eLTTmjyLD98QKBgB82S+Plcklpu3zUpnS+nGJn2Du7fYI7F+6cW2zXBn0N5lA+Mgt+kVkAUcFQD9uqkF4M51BO6kIXk10nt6vLAT2NM1S3MKW+XQBAI6l+uKSaYpK/VL3bEdVThwAYK5X7L5/5Z97bwdKeUmkFjhVCoJ0oGrzOiWLgGymUzct2UHSVAoGBAMb+7Cs+Ub0pMrmFBY6r52pbey1Uq0pglvRgMmhQU7sjx50r2GaA81zPer15WVM5/nNPYaoALYqg7jrPe/PjOT/fvpR+7SNg7DZ8QftANfYiY7jKifst/gDt9ePLPS6FedZ4XcJQgOVu34jicAFx64vPbS/zrddm4iEScSVijRBBAoGAXCheERsx8+n16Us/DttXFUa1nc7+D8WR6buM1QMZgQCVF2qp3XtM+FusCKL4+q1+dtag8svLjJFp9QbaAXqX8Zk7rn8wUHbDloPTPy9XWgrPowyL9MPU+e/Rq8Hr6TWPDBd4TU64YzIEfBQYpJXfZbXhVYmK3o7xHXKB1x4vvEM="; |
| | | alipayConfig.setPrivateKey(privateKey); |
| | | alipayConfig.setAppCertPath("pay/pro/appCertPublicKey.crt"); |
| | | alipayConfig.setAlipayPublicCertPath("pay/pro/alipayCertPublicKey_RSA2.crt"); |
| | | alipayConfig.setRootCertPath("pay/pro/alipayRootCert.crt"); |
| | | /** |
| | | * åç¬è½¬è´¦å°æ¯ä»å®è´¦æ· |
| | | * |
| | | * @param dto è½¬è´¦åæ° |
| | | * @return æ¯ä»å®è½¬è´¦åå· |
| | | */ |
| | | public static String transfer(AlipayTransferDTO dto) throws ApiException { |
| | | ApiClient defaultClient = Configuration.getDefaultApiClient(); |
| | | defaultClient.setAlipayConfig(alipayConfig); |
| | | AlipayFundTransUniApi api = new AlipayFundTransUniApi(); |
| | | AlipayFundTransUniTransferModel data = new AlipayFundTransUniTransferModel(); |
| | | data.setOutBizNo(dto.getOutBizNo()); |
| | | data.setTransAmount(dto.getTransAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()); |
| | | data.setBizScene("DIRECT_TRANSFER"); |
| | | data.setProductCode("TRANS_ACCOUNT_NO_PWD"); |
| | | data.setOrderTitle("ä½£éæç°"); |
| | | |
| | | return alipayConfig; |
| | | Participant payeeInfo = new Participant(); |
| | | payeeInfo.setIdentity(dto.getPayeeAccount()); |
| | | payeeInfo.setName(dto.getPayeeName()); |
| | | payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); |
| | | data.setPayeeInfo(payeeInfo); |
| | | |
| | | data.setRemark(dto.getRemark()); |
| | | data.setTransferSceneName("佣鿥é
¬"); |
| | | |
| | | List<TransferSceneReportInfo> reportInfos = new ArrayList<>(); |
| | | TransferSceneReportInfo reportInfo = new TransferSceneReportInfo(); |
| | | reportInfo.setInfoType("佣鿥é
¬è¯´æ"); |
| | | reportInfo.setInfoContent("ä½£éæç°"); |
| | | reportInfos.add(reportInfo); |
| | | data.setTransferSceneReportInfos(reportInfos); |
| | | |
| | | data.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}"); |
| | | |
| | | try { |
| | | AlipayFundTransUniTransferResponseModel response = api.transfer(data); |
| | | log.info("æ¯ä»å®è½¬è´¦æå, outBizNo={}, orderId={}", dto.getOutBizNo(), response.getOrderId()); |
| | | return response.getOrderId(); |
| | | } catch (ApiException e) { |
| | | AlipayFundTransUniTransferDefaultResponse errorObject = |
| | | (AlipayFundTransUniTransferDefaultResponse) e.getErrorObject(); |
| | | log.error("æ¯ä»å®è½¬è´¦å¤±è´¥, outBizNo={}, error={}", dto.getOutBizNo(), errorObject); |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), |
| | | "转账失败ï¼" + (errorObject != null ? errorObject.toString() : e.getMessage())); |
| | | } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.config.alipay; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * æ¯ä»å®é
ç½®å±æ§ |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Component |
| | | @ConfigurationProperties(prefix = "alipay.pay") |
| | | @Data |
| | | public class AlipayProperties { |
| | | |
| | | /** |
| | | * åºç¨ID |
| | | */ |
| | | private String appId; |
| | | |
| | | /** |
| | | * åºç¨ç§é¥ |
| | | */ |
| | | private String privateKey; |
| | | |
| | | /** |
| | | * åºç¨å
¬é¥è¯ä¹¦è·¯å¾ |
| | | */ |
| | | private String appCertPath; |
| | | |
| | | /** |
| | | * æ¯ä»å®å
¬é¥è¯ä¹¦è·¯å¾ |
| | | */ |
| | | private String alipayPublicCertPath; |
| | | |
| | | /** |
| | | * æ¯ä»å®æ ¹è¯ä¹¦è·¯å¾ |
| | | */ |
| | | private String rootCertPath; |
| | | } |
| | |
| | | import cn.binarywang.wx.miniapp.api.WxMaService; |
| | | import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; |
| | | import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; |
| | | import com.doumee.biz.system.SystemDictDataBiz; |
| | | import com.doumee.config.mybatis.SpringUtils; |
| | | import com.doumee.core.constants.Constants; |
| | | import com.github.binarywang.wxpay.config.WxPayConfig; |
| | | import com.github.binarywang.wxpay.constant.WxPayConstants; |
| | | import com.github.binarywang.wxpay.service.WxPayService; |
| | |
| | | import com.wechat.pay.java.core.Config; |
| | | import com.wechat.pay.java.core.RSAAutoCertificateConfig; |
| | | import com.wechat.pay.java.core.RSAPublicKeyConfig; |
| | | import com.wechat.pay.java.core.http.HostName; |
| | | import com.wechat.pay.java.core.notification.NotificationParser; |
| | | import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig; |
| | | import com.wechat.pay.java.service.billdownload.BillDownloadService; |
| | | import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiService; |
| | | import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension; |
| | | import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; |
| | | import com.wechat.pay.java.service.refund.RefundService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Configuration; |
| | |
| | | /** |
| | | * 微信å°ç¨åºç»ä»¶ |
| | | */ |
| | | @Slf4j |
| | | @Configuration |
| | | public class WxMiniConfig { |
| | | /********微信å°ç¨åºæå¡**********/ |
| | | public static WxMaService wxMaService; |
| | | /********微信å°ç¨åºæ¯ä»**********/ |
| | | /********微信å°ç¨åºæ¯ä» V2**********/ |
| | | public static WxPayService wxPayService; |
| | | /********微信APPæ¯ä»**********/ |
| | | public static WxPayService wxAppPayService; |
| | | |
| | | /********微信æ¯ä» V3**********/ |
| | | public static JsapiServiceExtension v3JsapiService; |
| | | public static RefundService v3RefundService; |
| | | public static NotificationParser v3NotificationParser; |
| | | |
| | | @Autowired |
| | | private WxPayProperties wxPayProperties; |
| | |
| | | void init() { |
| | | this.load_WxMaService(); |
| | | this.load_wxPayService(); |
| | | this.load_wxPayV3Service(); |
| | | // this.load_wxAppPayService(); |
| | | } |
| | | /** |
| | |
| | | config.setAppid(StringUtils.trimToNull(wxPayProperties.getAppId())); |
| | | config.setSecret(StringUtils.trimToNull(wxPayProperties.getAppSecret())); |
| | | config.setMsgDataFormat("JSON"); |
| | | //config.setToken(""); |
| | | //config.setAesKey(""); |
| | | WxMaService wxMaService = new WxMaServiceImpl(); |
| | | wxMaService.setWxMaConfig(config); |
| | | this.wxMaService = wxMaService; |
| | | } |
| | | |
| | | /** |
| | | * åå§å微信å°ç¨åºæ¯ä» |
| | | * åå§å微信å°ç¨åºæ¯ä» V2 |
| | | */ |
| | | public void load_wxPayService() { |
| | | WxPayConfig payConfig = new WxPayConfig(); |
| | |
| | | this.wxPayService = wxPayService; |
| | | } |
| | | |
| | | /** |
| | | * åå§å微信æ¯ä» V3ï¼JSAPI + 鿬¾ + åè°éªç¾ï¼ |
| | | */ |
| | | public void load_wxPayV3Service() { |
| | | try { |
| | | Config config = |
| | | new RSAPublicKeyConfig.Builder() |
| | | .merchantId(wxPayProperties.getMchId()) //微信æ¯ä»çåæ·å· |
| | | .privateKeyFromPath(wxPayProperties.getPrivateKeyPath()) // åæ·APIè¯ä¹¦ç§é¥çåæ¾è·¯å¾ |
| | | .merchantSerialNumber(wxPayProperties.getSerialNumer()) //åæ·APIè¯ä¹¦åºåå· |
| | | .publicKeyFromPath(wxPayProperties.getPubKeyPath()) //微信æ¯ä»å
¬é¥çåæ¾è·¯å¾ |
| | | .publicKeyId(wxPayProperties.getPublicKeyId()) //微信æ¯ä»å
¬é¥ID |
| | | .apiV3Key(wxPayProperties.getApiV3Key()) //APIv3å¯é¥ |
| | | .build(); |
| | | |
| | | |
| | | // æ¯ä»å
¬é¥é
ç½®ï¼ç¨äºåè°éªç¾ï¼ |
| | | RSAPublicKeyNotificationConfig notifyConfig = new RSAPublicKeyNotificationConfig.Builder() |
| | | .publicKeyFromPath(wxPayProperties.getPubKeyPath()) |
| | | .publicKeyId(wxPayProperties.getPublicKeyId()) |
| | | .apiV3Key(wxPayProperties.getApiV3Key()) |
| | | .build(); |
| | | |
| | | v3JsapiService = new JsapiServiceExtension.Builder().config(config).build(); |
| | | v3RefundService = new RefundService.Builder().config(config).build(); |
| | | v3NotificationParser = new NotificationParser(notifyConfig); |
| | | |
| | | log.info("微信æ¯ä»V3åå§åæå"); |
| | | } catch (Exception e) { |
| | | log.error("微信æ¯ä»V3åå§å失败: {}", e.getMessage(), e); |
| | | } |
| | | } |
| | | |
| | | // /** |
| | | // * åå§åAppæ¯ä» |
| | | // */ |
| | |
| | | private String notifyUrl; |
| | | |
| | | /** |
| | | * V3æ¯ä»åè°å°å |
| | | */ |
| | | private String v3NotifyUrl; |
| | | |
| | | /** |
| | | * V3鿬¾åè°å°å |
| | | */ |
| | | private String v3RefundNotifyUrl; |
| | | |
| | | /** |
| | | * æ¯ä»è¯ä¹¦(p12) |
| | | */ |
| | | private String keyPath; |
| | |
| | | */ |
| | | private String privateCertPath; |
| | | |
| | | |
| | | |
| | | /** |
| | | * æ¯ä»key |
| | | */ |
| | | private String privateKeyPath; |
| | | |
| | | |
| | | /** |
| | | * 微信æ¯ä»å
¬é¥ID |
| | | */ |
| | | private String publicKeyId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.config.wx; |
| | | |
| | | import com.doumee.core.constants.ResponseStatus; |
| | | import com.doumee.core.exception.BusinessException; |
| | | import com.doumee.core.utils.ID; |
| | | import com.wechat.pay.java.core.notification.RequestParam; |
| | | import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; |
| | | import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; |
| | | import com.wechat.pay.java.service.refund.model.AmountReq; |
| | | import com.wechat.pay.java.service.refund.model.CreateRequest; |
| | | import com.wechat.pay.java.service.refund.model.Refund; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 微信æ¯ä»V3çæ¬æå¡ï¼JSAPIä¸å + 鿬¾ + åè°éªç¾ï¼ |
| | | * |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class WxPayV3Service { |
| | | |
| | | @Autowired |
| | | private WxPayProperties wxPayProperties; |
| | | |
| | | /** |
| | | * JSAPIä¸åï¼è¿åå端è°èµ·æ¯ä»æéçåæ° |
| | | * |
| | | * @param outTradeNo åæ·è®¢åå· |
| | | * @param description ååæè¿° |
| | | * @param totalCents éé¢ï¼åï¼ |
| | | * @param openid ç¨æ·openid |
| | | * @param notifyUrl æ¯ä»åè°å°å |
| | | * @param attach éå æ°æ®ï¼åè°æ¶åæ ·è¿åï¼ç¨äºè·¯ç±ä¸åä¸å¡ï¼ |
| | | * @return å端è°èµ·æ¯ä»åæ°ï¼appId, timeStamp, nonceStr, package, signType, paySignï¼ |
| | | */ |
| | | public Map<String, String> createOrder(String outTradeNo, String description, |
| | | Long totalCents, String openid, |
| | | String notifyUrl, String attach) { |
| | | if (WxMiniConfig.v3JsapiService == null) { |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "微信æ¯ä»V3æªåå§å"); |
| | | } |
| | | try { |
| | | PrepayRequest request = new PrepayRequest(); |
| | | request.setAppid(wxPayProperties.getAppId()); |
| | | request.setMchid(wxPayProperties.getMchId()); |
| | | request.setDescription(description); |
| | | request.setOutTradeNo(outTradeNo); |
| | | request.setNotifyUrl(notifyUrl); |
| | | if (attach != null && !attach.isEmpty()) { |
| | | request.setAttach(attach); |
| | | } |
| | | |
| | | com.wechat.pay.java.service.payments.jsapi.model.Amount amount = |
| | | new com.wechat.pay.java.service.payments.jsapi.model.Amount(); |
| | | amount.setTotal(1);//totalCents.intValue()); |
| | | amount.setCurrency("CNY"); |
| | | request.setAmount(amount); |
| | | |
| | | com.wechat.pay.java.service.payments.jsapi.model.Payer payer = |
| | | new com.wechat.pay.java.service.payments.jsapi.model.Payer(); |
| | | payer.setOpenid(openid); |
| | | request.setPayer(payer); |
| | | |
| | | PrepayWithRequestPaymentResponse response = |
| | | WxMiniConfig.v3JsapiService.prepayWithRequestPayment(request); |
| | | |
| | | Map<String, String> result = new HashMap<>(); |
| | | result.put("appId", response.getAppId()); |
| | | result.put("timeStamp", response.getTimeStamp()); |
| | | result.put("nonceStr", response.getNonceStr()); |
| | | result.put("package", response.getPackageVal()); |
| | | result.put("signType", response.getSignType()); |
| | | result.put("paySign", response.getPaySign()); |
| | | return result; |
| | | } catch (Exception e) { |
| | | log.error("微信æ¯ä»V3ä¸å失败: {}", e.getMessage(), e); |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "æ¯ä»è°èµ·å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * V3鿬¾ |
| | | * |
| | | * @param outTradeNo åæ·è®¢åå· |
| | | * @param totalCents å订åéé¢ï¼åï¼ |
| | | * @param refundCents 鿬¾éé¢ï¼åï¼ |
| | | * @param reason 鿬¾åå |
| | | * @param notifyUrl 鿬¾åè°å°å |
| | | * @return Refund 鿬¾ç»æï¼å
å« outRefundNoãstatus çï¼ |
| | | */ |
| | | public Refund refund(String outTradeNo, Long totalCents, Long refundCents, |
| | | String reason, String notifyUrl) { |
| | | if (WxMiniConfig.v3RefundService == null) { |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "微信æ¯ä»V3æªåå§å"); |
| | | } |
| | | try { |
| | | String outRefundNo = ID.nextGUID(); |
| | | |
| | | CreateRequest request = new CreateRequest(); |
| | | request.setOutTradeNo(outTradeNo); |
| | | request.setOutRefundNo(outRefundNo); |
| | | request.setReason(reason); |
| | | request.setNotifyUrl(notifyUrl); |
| | | |
| | | AmountReq amount = new AmountReq(); |
| | | amount.setRefund(1L);//refundCents); |
| | | amount.setTotal(1L);//totalCents); |
| | | amount.setCurrency("CNY"); |
| | | request.setAmount(amount); |
| | | |
| | | Refund result = WxMiniConfig.v3RefundService.create(request); |
| | | log.info("微信æ¯ä»V3鿬¾ç³è¯·ç»æ, outTradeNo={}, outRefundNo={}, status={}", |
| | | outTradeNo, outRefundNo, result.getStatus()); |
| | | return result; |
| | | } catch (Exception e) { |
| | | log.error("微信æ¯ä»V3鿬¾å¤±è´¥: {}", e.getMessage(), e); |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "鿬¾å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è§£æV3æ¯ä»åè°éç¥ |
| | | * |
| | | * @param serialNumber è¯ä¹¦åºåå·ï¼Wechatpay-Serial headerï¼ |
| | | * @param timestamp æ¶é´æ³ï¼Wechatpay-Timestamp headerï¼ |
| | | * @param nonce éæºä¸²ï¼Wechatpay-Nonce headerï¼ |
| | | * @param signature ç¾åï¼Wechatpay-Signature headerï¼ |
| | | * @param body 请æ±ä½JSON |
| | | * @return è§£æåçTransaction对象 |
| | | */ |
| | | public com.wechat.pay.java.service.payments.model.Transaction parsePayNotify( |
| | | String serialNumber, String timestamp, String nonce, |
| | | String signature, String body) { |
| | | try { |
| | | RequestParam requestParam = new RequestParam.Builder() |
| | | .serialNumber(serialNumber) |
| | | .timestamp(timestamp) |
| | | .nonce(nonce) |
| | | .signature(signature) |
| | | .body(body) |
| | | .build(); |
| | | |
| | | return WxMiniConfig.v3NotificationParser.parse(requestParam, |
| | | com.wechat.pay.java.service.payments.model.Transaction.class); |
| | | } catch (Exception e) { |
| | | log.error("微信æ¯ä»V3åè°éªç¾å¤±è´¥: {}", e.getMessage(), e); |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "åè°éªç¾å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è§£æV3鿬¾åè°éç¥ |
| | | * |
| | | * @param serialNumber è¯ä¹¦åºåå· |
| | | * @param timestamp æ¶é´æ³ |
| | | * @param nonce éæºä¸² |
| | | * @param signature ç¾å |
| | | * @param body 请æ±ä½JSON |
| | | * @return è§£æåçRefundNotification对象 |
| | | */ |
| | | public com.wechat.pay.java.service.refund.model.RefundNotification parseRefundNotify( |
| | | String serialNumber, String timestamp, String nonce, |
| | | String signature, String body) { |
| | | try { |
| | | RequestParam requestParam = new RequestParam.Builder() |
| | | .serialNumber(serialNumber) |
| | | .timestamp(timestamp) |
| | | .nonce(nonce) |
| | | .signature(signature) |
| | | .body(body) |
| | | .build(); |
| | | return WxMiniConfig.v3NotificationParser.parse(requestParam, |
| | | com.wechat.pay.java.service.refund.model.RefundNotification.class); |
| | | } catch (Exception e) { |
| | | log.error("微信æ¯ä»V3鿬¾åè°éªç¾å¤±è´¥: {}", e.getMessage(), e); |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鿬¾åè°éªç¾å¤±è´¥"); |
| | | } |
| | | } |
| | | } |
| | |
| | | public static final int ORDER_LOG_ASSIGN_DRIVER = 3; // ææ´¾å¸æº |
| | | public static final int ORDER_LOG_CANCEL = 4; // åæ¶è®¢å |
| | | public static final int ORDER_LOG_CONFIRM_ARRIVE = 5; // 确认顾客å°åº |
| | | public static final int ORDER_LOG_DRIVER_PICKUP = 6; // 叿ºå®æåä»¶ |
| | | |
| | | public static final String SUCCESS = "SUCCESS"; |
| | | public static final String FAIL = "FAIL"; |
| | |
| | | |
| | | |
| | | |
| | | public enum WorkOrderStatus{ |
| | | waitConfirm( 0, "å¾
åé
WTS","{title}䏿¥","","å¾
åé
WTS" ), |
| | | waitAllocation(1, "å¾
åé
ä»»å¡","å¾
åé
ä»»å¡","","å¾
åé
ä»»å¡"), |
| | | waitDeal(2, "å¾
å¤ç","å¾
å¤ç","","å¾
å·¥ç¨å¸å¤ç"), |
| | | sheClose(3, "已解å³","SHEå·²å
³é","","SHEå·²å
³é"), |
| | | wtsClose(4, "已解å³","WTSå·²å
³é","","WTSå·²å
³é"), |
| | | close(5, "已解å³","已解å³","","å·¥ç¨å¸å
³é"), |
| | | urge (6, "å¬ä¿","","","") |
| | | ; |
| | | |
| | | private int status; |
| | | private String statusInfo; |
| | | private String statusName; |
| | | private String logTitle; |
| | | private String noticeContent; |
| | | |
| | | // æé æ¹æ³ |
| | | WorkOrderStatus(int status, String statusInfo,String logTitle,String noticeContent,String statusName ) { |
| | | this.status = status; |
| | | this.statusInfo = statusInfo; |
| | | this.logTitle = logTitle; |
| | | this.noticeContent = noticeContent; |
| | | this.statusName = statusName; |
| | | } |
| | | public static String getName(int index) { |
| | | for (WorkOrderStatus c : WorkOrderStatus.values()) { |
| | | if (c.getKey() == index) { |
| | | return c.statusInfo; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | public static String getStatusName(int index) { |
| | | for (WorkOrderStatus c : WorkOrderStatus.values()) { |
| | | if (c.getKey() == index) { |
| | | return c.statusName; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public int getKey() { |
| | | return status; |
| | | } |
| | | |
| | | public void setKey(int key) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public int getStatus() { |
| | | return status; |
| | | } |
| | | |
| | | public void setStatus(int status) { |
| | | this.status = status; |
| | | } |
| | | |
| | | public String getStatusName() { |
| | | return statusName; |
| | | } |
| | | |
| | | public void setStatusName(String statusName) { |
| | | this.statusName = statusName; |
| | | } |
| | | |
| | | public String getStatusInfo() { |
| | | return statusInfo; |
| | | } |
| | | |
| | | public void setStatusInfo(String statusInfo) { |
| | | this.statusInfo = statusInfo; |
| | | } |
| | | |
| | | public String getLogTitle() { |
| | | return logTitle; |
| | | } |
| | | |
| | | public void setLogTitle(String logTitle) { |
| | | this.logTitle = logTitle; |
| | | } |
| | | |
| | | public String getNoticeContent() { |
| | | return noticeContent; |
| | | } |
| | | |
| | | public void setNoticeContent(String noticeContent) { |
| | | this.noticeContent = noticeContent; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * éä»¶ç±»åï¼å¯¹åº multifile.objTypeï¼ |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * 订åç«å
ä¿¡éç¥æä¸¾ |
| | | * title: éç¥æ é¢ |
| | | * content: éç¥ææ¡æ¨¡æ¿ï¼å ä½ç¬¦ç¨ {xxx} 表示 |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MemberOrderNotify { |
| | | WAIT_PAY("waitPay", "订åå¾
æ¯ä»", "æ¨çè¡æè®¢åï¼{orderNo}å·²å建ï¼è¯·å¨{timeout}åéå
宿æ¯ä»ï¼è¶
æ¶å°èªå¨åæ¶"), |
| | | WAIT_VERIFY("waitVerify", "订åå¾
æ ¸éª", "æ¨çè¡æè®¢åï¼{orderNo}å·²æäº¤ï¼çå¾
é¨åºæ ¸éªç©åä¿¡æ¯ï¼åä»¶ç {storeCode}"), |
| | | WAIT_GRAB("waitGrab", "订åå¾
æ¢å", "æ¨çè¡æè®¢åï¼{orderNo}å·²æ ¸éªï¼æ£å¨ä¸ºæ¨å®æå件叿º"), |
| | | WAIT_PICKUP_REMIND("waitPickupRemind", "订åå¾
åä»¶", "订å{orderNo}è¡æå·²å¯åï¼è¯·è®°å¾å¨é¢çº¦åä»¶æ¶é´ååä»¶ç å徿å®é¨åºåå"), |
| | | WAIT_PICKUP_GRABBED("waitPickupGrabbed", "订åå·²æ¢å", "æ¨çè¡æè®¢åï¼å·²æå¸æº{driverName}æ¢åï¼æ£åå¾åä»¶å°ç¹"), |
| | | DELIVERING("delivering", "订åé
éä¸", "æ¨çè¡æè®¢åï¼{orderNo}å·²ç±å¸æº{driverName}åä»¶ï¼æ£è¿å¾ç®çå°"), |
| | | ARRIVED_NO_SHOP("arrivedNoShop", "订åå·²éè¾¾", "æ¨çè¡æè®¢åï¼{orderNo}å·²éè¾¾{destination},è¯·åæ¶ç¡®è®¤æ¶è´§"), |
| | | ARRIVED_HAS_SHOP("arrivedHasShop", "订åå·²éè¾¾", "æ¨çè¡æè®¢åï¼{orderNo}å·²éè¾¾{destination},è¯·åæ¶åä»¶ï¼åä»¶ç {pickupCode}"), |
| | | FINISHED("finished", "订å已宿", "æ¨çè¡æè®¢åï¼{orderNo}å·²å®æï¼æè°¢æ¨çæ¯æï¼è¯·å¯¹æ¬æ¬¡æå¡ååºè¯ä»·"), |
| | | EVALUATED("evaluated", "订åå·²è¯ä»·", "æ¨çè¡æè®¢åï¼{orderNo}è¯ä»·å·²æäº¤ï¼æè°¢æ¨çç¨å¿è¯ä»·ï¼ç¥æ¨åºè¡é¡ºå©ï¼æ
éæå¿«!"), |
| | | CANCELLED("cancelled", "订å已忶", "æ¨çè¡æè®¢åï¼{orderNo}å·²åæ¶ï¼æè°¢æ¨çæ¯æï¼æ¬¢è¿ä¸æ¬¡åä¼!"), |
| | | DRIVER_CHANGED("driverChanged", "叿ºåæ´æé", "æ¨çè¡æè®¢åï¼{orderNo}å叿ºå·²åæ¶ï¼ç³»ç»æ£å¨ä¸ºæ¨å¹é
æ°å¸æºï¼è¯·çæéç¥ã"), |
| | | REFUNDING("refunding", "订å鿬¾ä¸", "æ¨çè¡æè®¢åï¼{orderNo}鿬¾ç³è¯·å·²æäº¤ï¼å¹³å°ä¼å°å°½å¿«ä¸ºæ¨å¤ç鿬¾"), |
| | | REFUNDED("refunded", "订å已鿬¾", "æ¨çè¡æè®¢åï¼{orderNo}鿬¾å·²å®æï¼éé¢{amount}å
å°åè·¯éåï¼è¯·æ³¨ææ¥æ¶") |
| | | ; |
| | | |
| | | private final String key; |
| | | private final String title; |
| | | private final String content; |
| | | |
| | | /** |
| | | * æ ¼å¼åéç¥å
容 |
| | | * @param params é®å¼å¯¹ï¼å¦ "orderNo","123" 交æ¿ä¼ å
¥ |
| | | */ |
| | | public String format(String... params) { |
| | | String result = this.content; |
| | | for (int i = 0; i < params.length - 1; i += 2) { |
| | | result = result.replace("{" + params[i] + "}", params[i + 1]); |
| | | } |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * é¨åºè®¢åç«å
ä¿¡éç¥æä¸¾ |
| | | * title: éç¥æ é¢ |
| | | * content: éç¥ææ¡æ¨¡æ¿ï¼å ä½ç¬¦ç¨ {xxx} 表示 |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum ShopOrderNotify { |
| | | WAIT_VERIFY("waitVerify", "订åå¾
æ ¸éª", "æ°è¡æè®¢åï¼{orderNo}å·²æ¯ä»ï¼è¯·å°½å¿«æ ¸éªç¨æ·ç©åä¿¡æ¯"), |
| | | WAIT_PICKUP("waitPickup", "订åå¾
åä»¶", "è¡æè®¢åï¼{orderNo}å·²æ¢åï¼çå¾
{name}åä»¶"), |
| | | REFUNDING("refunding", "订å鿬¾ä¸", "è¡æè®¢åï¼{orderNo}ç¨æ·æäº¤é款ç³è¯·ï¼è¯·ç¥æ"), |
| | | DELIVERING("delivering", "订åé
éä¸", "è¡æè®¢åï¼{orderNo}å·²ç±å¸æº{driverName}åä»¶ï¼æ£å¨é
éä¸"), |
| | | ARRIVED("arrived", "å·²éè¾¾", "è¡æè®¢åï¼{orderNo}å·²éè¾¾{destination},请èç³»ç¨æ·ç¡®è®¤ç¾æ¶"), |
| | | FINISHED("finished", "订å已宿", "è¡æè®¢åï¼{orderNo}已宿ï¼ç¸å
³è®¢åç»ç®ä¼å¨{settleDays}ä¸ªå·¥ä½æ¥å
宿"), |
| | | EVALUATED("evaluated", "订åå·²è¯ä»·", "è¡æè®¢åï¼{orderNo}ç¨æ·å·²å®æè¯ä»·ï¼å¯æ¥çè¯ä»·å
容"), |
| | | SETTLED("settled", "订åç»ç®", "è¡æè®¢åï¼{orderNo}å¹³å°å·²å®æç»ç®ï¼éé¢ä¸º{amount}å
ï¼è¯·æ³¨ææ¥æ¶ã") |
| | | ; |
| | | |
| | | private final String key; |
| | | private final String title; |
| | | private final String content; |
| | | |
| | | /** |
| | | * æ ¼å¼åéç¥å
容 |
| | | * @param params é®å¼å¯¹ï¼å¦ "orderNo","123" 交æ¿ä¼ å
¥ |
| | | */ |
| | | public String format(String... params) { |
| | | String result = this.content; |
| | | for (int i = 0; i < params.length - 1; i += 2) { |
| | | result = result.replace("{" + params[i] + "}", params[i + 1]); |
| | | } |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¾å°request对象 |
| | | * |
| | | * @return |
| | |
| | | @Slf4j |
| | | public class AliSmsService { |
| | | |
| | | private final static String ACCESS_KEY_ID = "LTAI5tMkg7wwV74a8H6Bm3Ej"; |
| | | private final static String ACCESS_KEY_SECRET = "FcHKST36sfwfo706L6bvrweGFIbp3n"; |
| | | private final static String SING_NAME = "æ©æ¡å¤©ä¸ç§æ"; |
| | | private final static String ACCESS_KEY_ID = "LTAI5t835zTU4aaYpGHJCccJ"; |
| | | private final static String ACCESS_KEY_SECRET = "98sAF2NchWVuIzu62zcLq0Ns7LIQTp"; |
| | | private final static String SING_NAME = "å京ä¸åªé¹¤"; |
| | | |
| | | |
| | | public static void main(String[] args) { |
| | | Map<String,Object> tempParam = new java.util.HashMap<>(); |
| | | tempParam.put("order","è¡èéæå·¥"); |
| | | tempParam.put("time1","07-23"); |
| | | tempParam.put("time2","07-24"); |
| | | AliSmsService.sendSms("18055151023","SMS_491055243", JSONObject.toJSONString(tempParam)); |
| | | tempParam.put("code","1234"); |
| | | AliSmsService.sendSms("15345690849","SMS_333770877", JSONObject.toJSONString(tempParam)); |
| | | } |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.core.utils.geocode; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.doumee.core.utils.Http; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.URLEncoder; |
| | | |
| | | /** |
| | | * é«å¾·å°å¾å·¥å
·ç±» |
| | | * |
| | | * @Author : Rk |
| | | * @create 2026/4/20 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class MapUtil { |
| | | |
| | | private static String amapKey; |
| | | |
| | | /** éå°çè§£æ */ |
| | | private static final String GEO_URL = "https://restapi.amap.com/v3/geocode/regeo"; |
| | | |
| | | /** 驾车路å¾è§å */ |
| | | private static final String DRIVING_URL = "https://restapi.amap.com/v3/direction/driving"; |
| | | |
| | | /** éªè¡è·¯å¾è§å */ |
| | | private static final String BICYCLING_URL = "https://restapi.amap.com/v4/direction/bicycling"; |
| | | |
| | | @Value("${geocode_map_key:}") |
| | | public void setAmapKey(String amapKey) { |
| | | MapUtil.amapKey = amapKey; |
| | | } |
| | | |
| | | /** |
| | | * éå°çè§£æ - æ ¹æ®ç»çº¬åº¦è·åå°åä¿¡æ¯ |
| | | * é«å¾·åæ 系为 lng,latï¼ä¸è
¾è®¯ lat,lng ç¸åï¼ |
| | | * |
| | | * @param lat 纬度 |
| | | * @param lng ç»åº¦ |
| | | * @return å
å« ad_info åå¸ä¿¡æ¯ç JSONObjectï¼å
¼å®¹è
¾è®¯è¿åæ ¼å¼ï¼ |
| | | */ |
| | | public static JSONObject reverseGeocode(double lat, double lng) { |
| | | try { |
| | | String url = GEO_URL |
| | | + "?key=" + amapKey |
| | | + "&location=" + lng + "," + lat; |
| | | |
| | | log.info("é«å¾·å°å¾éå°çè§£æè¯·æ±: lat={}, lng={}", lat, lng); |
| | | |
| | | JSONObject json = new Http().build(url) |
| | | .setConnectTimeout(5000) |
| | | .setReadTimeout(10000) |
| | | .get() |
| | | .toJSONObject(); |
| | | |
| | | log.info("é«å¾·å°å¾éå°çè§£æååº: {}", json); |
| | | |
| | | if (!"1".equals(json.getString("status"))) { |
| | | throw new RuntimeException("é«å¾·å°å¾éå°çè§£æå¤±è´¥: " + json.getString("info")); |
| | | } |
| | | |
| | | // 转æ¢ä¸ºå
¼å®¹è
¾è®¯è¿åæ ¼å¼: result.ad_info.city / adcode / district |
| | | JSONObject regeocode = json.getJSONObject("regeocode"); |
| | | JSONObject addressComponent = regeocode.getJSONObject("addressComponent"); |
| | | |
| | | JSONObject adInfo = new JSONObject(); |
| | | adInfo.put("adcode", addressComponent.getString("adcode")); |
| | | adInfo.put("city", addressComponent.getString("city")); |
| | | adInfo.put("district", addressComponent.getString("district")); |
| | | adInfo.put("province", addressComponent.getString("province")); |
| | | adInfo.put("nation", addressComponent.getString("country")); |
| | | |
| | | JSONObject result = new JSONObject(); |
| | | result.put("ad_info", adInfo); |
| | | result.put("formatted_addresses", regeocode.getString("formatted_address")); |
| | | return result; |
| | | } catch (IOException e) { |
| | | log.error("é«å¾·å°å¾éå°çè§£æå¼å¸¸", e); |
| | | throw new RuntimeException("é«å¾·å°å¾éå°çè§£æå¼å¸¸", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤æä¸¤ä¸ªç»çº¬åº¦æ¯å¦å¨åä¸ä¸ªåå¸ |
| | | */ |
| | | public static boolean isSameCity(double lat1, double lng1, double lat2, double lng2) { |
| | | JSONObject result1 = reverseGeocode(lat1, lng1); |
| | | JSONObject result2 = reverseGeocode(lat2, lng2); |
| | | |
| | | String city1 = result1.getJSONObject("ad_info").getString("city"); |
| | | String city2 = result2.getJSONObject("ad_info").getString("city"); |
| | | |
| | | log.info("夿åå: ({},{}) => city={}, ({},{}) => city={}", lat1, lng1, city1, lat2, lng2, city2); |
| | | |
| | | return city1 != null && city1.equals(city2); |
| | | } |
| | | |
| | | /** |
| | | * è·¯å¾è§åï¼ç»ä¸å
¥å£ï¼ |
| | | * å
鍿 ¹æ® mode è°ç¨é«å¾·ä¸åçè·¯å¾è§åæ¥å£ |
| | | * |
| | | * @param mode 模å¼ï¼driving(驾车)ãbicycling(éªè¡) |
| | | * @param from èµ·ç¹ï¼æ ¼å¼ï¼lat,lng |
| | | * @param to ç»ç¹ï¼æ ¼å¼ï¼lat,lng |
| | | * @return JSONObject å
å« distance(ç±³) å duration(ç§) |
| | | */ |
| | | public static JSONObject direction(String mode, String from, String to) { |
| | | // é«å¾·åæ 系为 lng,lat |
| | | String[] fromArr = from.split(","); |
| | | String[] toArr = to.split(","); |
| | | String origin = fromArr[1] + "," + fromArr[0]; // lng,lat |
| | | String destination = toArr[1] + "," + toArr[0]; // lng,lat |
| | | |
| | | try { |
| | | String url; |
| | | if ("bicycling".equals(mode)) { |
| | | url = BICYCLING_URL |
| | | + "?key=" + amapKey |
| | | + "&origin=" + URLEncoder.encode(origin, "UTF-8") |
| | | + "&destination=" + URLEncoder.encode(destination, "UTF-8"); |
| | | } else { |
| | | // é»è®¤é©¾è½¦ |
| | | url = DRIVING_URL |
| | | + "?key=" + amapKey |
| | | + "&origin=" + URLEncoder.encode(origin, "UTF-8") |
| | | + "&destination=" + URLEncoder.encode(destination, "UTF-8"); |
| | | } |
| | | |
| | | log.info("é«å¾·å°å¾è·¯å¾è§å请æ±: mode={}, from={}, to={}", mode, from, to); |
| | | |
| | | JSONObject json = new Http().build(url) |
| | | .setConnectTimeout(5000) |
| | | .setReadTimeout(10000) |
| | | .get() |
| | | .toJSONObject(); |
| | | |
| | | log.info("é«å¾·å°å¾è·¯å¾è§åååº: {}", json); |
| | | |
| | | if (!"1".equals(json.getString("status"))) { |
| | | throw new RuntimeException("é«å¾·å°å¾è·¯å¾è§å失败: " + json.getString("info")); |
| | | } |
| | | |
| | | // æåç¬¬ä¸æ¡è·¯å¾ç distance å duration |
| | | JSONObject routeData; |
| | | if ("bicycling".equals(mode)) { |
| | | routeData = json.getJSONObject("data"); |
| | | } else { |
| | | routeData = json.getJSONObject("route"); |
| | | } |
| | | |
| | | JSONObject path = routeData.getJSONArray("paths").getJSONObject(0); |
| | | long distance = path.getLongValue("distance"); |
| | | long duration = path.getLongValue("duration"); |
| | | |
| | | JSONObject result = new JSONObject(); |
| | | result.put("distance", distance); |
| | | result.put("duration", duration); |
| | | return result; |
| | | } catch (IOException e) { |
| | | log.error("é«å¾·å°å¾è·¯å¾è§åå¼å¸¸", e); |
| | | throw new RuntimeException("é«å¾·å°å¾è·¯å¾è§åå¼å¸¸", e); |
| | | } |
| | | } |
| | | } |
| ÎļþÃû´Ó server/services/src/main/java/com/doumee/core/utils/Tencent/MapUtil.java ÐÞ¸Ä |
| | |
| | | package com.doumee.core.utils.Tencent; |
| | | package com.doumee.core.utils.tencent; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | |
| | | * @create 2026/4/14 15:58 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | //@Component |
| | | public class MapUtil { |
| | | |
| | | private static String tencentKey; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.dao.business; |
| | | |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.github.yulichang.base.MPJBaseMapper; |
| | | |
| | | /** |
| | | * æ¶æ¯éç¥ä¿¡æ¯Mapper |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | public interface NoticeMapper extends MPJBaseMapper<Notice> { |
| | | } |
| | |
| | | @ApiModelProperty(value = "å®ä½çº¬åº¦", example = "39.915") |
| | | private Double latitude; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®æç°è´¦æ·") |
| | | private String aliAccount; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®å®åå§å") |
| | | private String aliName; |
| | | |
| | | @ApiModelProperty(value = "车è¾ç
§çå表") |
| | | @TableField(exist = false) |
| | | private List<Multifile> carImgList = new ArrayList<>(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.dao.business.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * æ¶æ¯éç¥ä¿¡æ¯ |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Data |
| | | @ApiModel("æ¶æ¯éç¥ä¿¡æ¯") |
| | | @TableName("`notice`") |
| | | public class Notice { |
| | | |
| | | @TableId(type = IdType.AUTO) |
| | | @ApiModelProperty(value = "主é®", example = "1") |
| | | private Integer id; |
| | | |
| | | @ApiModelProperty(value = "å建人ç¼ç ", example = "1") |
| | | private Integer creator; |
| | | |
| | | @ApiModelProperty(value = "å建æ¶é´") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date createDate; |
| | | |
| | | @ApiModelProperty(value = "æ´æ°äººç¼ç ", example = "1") |
| | | private Integer editor; |
| | | |
| | | @ApiModelProperty(value = "æ´æ°æ¶é´") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date editDate; |
| | | |
| | | @ApiModelProperty(value = "æ¯å¦å é¤ 0å¦ 1æ¯", example = "0") |
| | | private Integer isdeleted; |
| | | |
| | | @ApiModelProperty(value = "夿³¨") |
| | | private String remark; |
| | | |
| | | @ApiModelProperty(value = "ç¨æ·ç±»åï¼0=ä¼åç¨æ·ï¼1=叿ºï¼2=åºéºäººå", example = "0") |
| | | private Integer userType; |
| | | |
| | | @ApiModelProperty(value = "ç¨æ·ä¸»é®ï¼member/driver_info/shop_infoï¼", example = "1") |
| | | private Integer userId; |
| | | |
| | | @ApiModelProperty(value = "æ é¢") |
| | | private String title; |
| | | |
| | | @ApiModelProperty(value = "å
容") |
| | | private String content; |
| | | |
| | | @ApiModelProperty(value = "对象ç¼ç ", example = "1") |
| | | private Integer objId; |
| | | |
| | | @ApiModelProperty(value = "对象类åï¼0=订åç±»åï¼99=å
¶ä»ç±»å", example = "0") |
| | | private Integer objType; |
| | | |
| | | @ApiModelProperty(value = "ç¶æï¼0=æªè¯»ï¼1=已读", example = "0") |
| | | private Integer status; |
| | | |
| | | } |
| | |
| | | @ApiModelProperty(value = "平尿ä½äººï¼type=1使ç¨ï¼", example = "0") |
| | | private Integer userId; |
| | | |
| | | @ApiModelProperty(value = "鿬¾ç¶æï¼0=鿬¾ä¸ï¼1=鿬¾æåï¼2=鿬¾å¤±è´¥", example = "0") |
| | | private Integer status; |
| | | |
| | | |
| | | } |
| | |
| | | @ApiModelProperty(value = "æ¯ä»å®æç°è´¦æ·") |
| | | private String aliAccount; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®å®åå§å") |
| | | private String aliName; |
| | | |
| | | @ApiModelProperty(value = "è¥ä¸æ¶é´") |
| | | private String shopHours; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.dao.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æ¯ä»å®åç¬è½¬è´¦è¯·æ±åæ° |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Data |
| | | public class AlipayTransferDTO { |
| | | |
| | | /** |
| | | * åæ·ä¾§å¯ä¸è®¢åå· |
| | | */ |
| | | private String outBizNo; |
| | | |
| | | /** |
| | | * 转账éé¢ï¼å
ï¼ |
| | | */ |
| | | private BigDecimal transAmount; |
| | | |
| | | /** |
| | | * æ¶æ¬¾æ¹æ¯ä»å®è´¦å· |
| | | */ |
| | | private String payeeAccount; |
| | | |
| | | /** |
| | | * æ¶æ¬¾æ¹å§å |
| | | */ |
| | | private String payeeName; |
| | | |
| | | /** |
| | | * ä¸å¡å¤æ³¨ |
| | | */ |
| | | private String remark; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.dao.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import javax.validation.constraints.Size; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 叿ºå®æåä»¶è¯·æ± |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Data |
| | | @ApiModel("叿ºå®æå件请æ±") |
| | | public class DriverPickupDTO { |
| | | |
| | | @NotNull(message = "订å主é®ä¸è½ä¸ºç©º") |
| | | @ApiModelProperty(value = "订å主é®", required = true, example = "1") |
| | | private Integer orderId; |
| | | |
| | | @NotNull(message = "åä»¶å¾çä¸è½ä¸ºç©º") |
| | | @Size(min = 1, max = 3, message = "åä»¶å¾ç1-3å¼ ") |
| | | @ApiModelProperty(value = "åä»¶å¾çåè¡¨ï¼æå¤3å¼ ï¼", required = true) |
| | | private List<String> images; |
| | | } |
| | |
| | | @ApiModelProperty(value = "å
¶ä»èµæç
§çï¼æå¤3å¼ ï¼mutifile objType=8ï¼") |
| | | private List<String> otherImgUrls; |
| | | |
| | | @NotEmpty(message = "æ¯ä»å®æç°è´¦æ·ä¸è½ä¸ºç©º") |
| | | @ApiModelProperty(value = "æ¯ä»å®æç°è´¦æ·", required = true) |
| | | private String aliAccount; |
| | | |
| | | @NotEmpty(message = "æ¯ä»å®å®åå§åä¸è½ä¸ºç©º") |
| | | @ApiModelProperty(value = "æ¯ä»å®å®åå§å", required = true) |
| | | private String aliName; |
| | | |
| | | } |
| | |
| | | @ApiModelProperty(value = "æ¯ä»å®æç°è´¦æ·", required = true) |
| | | @NotBlank(message = "æ¯ä»å®æç°è´¦æ·ä¸è½ä¸ºç©º") |
| | | private String aliAccount; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®å®åå§å", required = true) |
| | | @NotBlank(message = "æ¯ä»å®å®åå§åä¸è½ä¸ºç©º") |
| | | private String aliName; |
| | | } |
| | |
| | | @Size(max = 3, message = "社ä¿ç¼´çº³è¯ææå¤3å¼ ") |
| | | private List<String> socialSecurityImgs; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®æç°è´¦æ·", required = true) |
| | | @NotBlank(message = "æ¯ä»å®æç°è´¦æ·ä¸è½ä¸ºç©º") |
| | | private String aliAccount; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®å®åå§å", required = true) |
| | | @NotBlank(message = "æ¯ä»å®å®åå§åä¸è½ä¸ºç©º") |
| | | private String aliName; |
| | | |
| | | } |
| | |
| | | @ApiModelProperty(value = "éç§åè®®") |
| | | private String privacyAgreement; |
| | | |
| | | @ApiModelProperty(value = "æå¡ä»ç»") |
| | | @ApiModelProperty(value = "è§èé¡»ç¥") |
| | | private String serverIntroduce; |
| | | } |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | |
| | | @ApiModelProperty(value = "审æ¹äººåç§°") |
| | | private String auditName; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®æç°è´¦æ·") |
| | | private String aliAccount; |
| | | |
| | | @ApiModelProperty(value = "æ¯ä»å®å®åå§å") |
| | | private String aliName; |
| | | |
| | | @ApiModelProperty(value = "OPENID") |
| | | private String openid; |
| | |
| | | import com.doumee.dao.dto.DriverGrabOrderDTO; |
| | | import com.doumee.dao.business.model.DriverInfo; |
| | | import com.doumee.dao.dto.DriverLoginRequest; |
| | | import com.doumee.dao.dto.DriverPickupDTO; |
| | | import com.doumee.dao.dto.DriverRegisterRequest; |
| | | import com.doumee.dao.dto.DriverVerifyRequest; |
| | | import com.doumee.dao.vo.AccountResponse; |
| | |
| | | */ |
| | | void cancelOrder(Integer driverId, Integer orderId, String reason); |
| | | |
| | | /** |
| | | * 叿ºæ¢åï¼è®¢åç¶æä»å·²å¯å(2)å为已æ¥å(3) |
| | | * |
| | | * @param driverId 叿ºä¸»é® |
| | | * @param orderId 订åä¸»é® |
| | | */ |
| | | void grabOrder(Integer driverId, Integer orderId); |
| | | |
| | | /** |
| | | * 叿ºå®æåä»¶ï¼è®¢åç¶æä»å·²æ¥å(3)å为派éä¸(4) |
| | | * |
| | | * @param driverId 叿ºä¸»é® |
| | | * @param dto å件请æ±åæ° |
| | | */ |
| | | void confirmPickup(Integer driverId, DriverPickupDTO dto); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.service.business; |
| | | |
| | | import com.doumee.core.model.PageData; |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.dao.business.model.Notice; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ¶æ¯éç¥ä¿¡æ¯Serviceå®ä¹ |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | public interface NoticeService { |
| | | |
| | | Integer create(Notice notice); |
| | | |
| | | void deleteById(Integer id); |
| | | |
| | | void delete(Notice notice); |
| | | |
| | | void deleteByIdInBatch(List<Integer> ids); |
| | | |
| | | void updateById(Notice notice); |
| | | |
| | | void updateByIdInBatch(List<Notice> notices); |
| | | |
| | | Notice findById(Integer id); |
| | | |
| | | Notice findOne(Notice notice); |
| | | |
| | | List<Notice> findList(Notice notice); |
| | | |
| | | PageData<Notice> findPage(PageWrap<Notice> pageWrap); |
| | | |
| | | long count(Notice notice); |
| | | } |
| | |
| | | import com.doumee.dao.business.model.Orders; |
| | | import com.doumee.dao.business.model.OrdersDetail; |
| | | import com.doumee.dao.business.model.Revenue; |
| | | import com.doumee.dao.dto.*; |
| | | import com.doumee.dao.vo.AccountResponse; |
| | | import com.doumee.dao.vo.DriverCenterVO; |
| | | import com.doumee.dao.vo.DriverGrabOrderVO; |
| | | import com.doumee.dao.vo.DriverOrderDetailVO; |
| | | import com.doumee.dao.dto.AuditDTO; |
| | | import com.doumee.dao.dto.ChangeStatusDTO; |
| | | import com.doumee.dao.dto.DriverLoginRequest; |
| | | import com.doumee.dao.dto.DriverRegisterRequest; |
| | | import com.doumee.dao.dto.DriverVerifyRequest; |
| | | import com.doumee.dao.dto.DriverActiveOrderDTO; |
| | | import com.doumee.dao.dto.DriverGrabOrderDTO; |
| | | import com.doumee.core.utils.aliyun.AliSmsService; |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.doumee.service.business.DriverInfoService; |
| | | import com.doumee.service.business.NoticeService; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import org.apache.commons.lang3.RandomStringUtils; |
| | |
| | | |
| | | @Autowired |
| | | private OperationConfigBiz operationConfigBiz; |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | /** |
| | | * åé订åç«å
ä¿¡éç¥ |
| | | */ |
| | | private void sendOrderNotice(Integer memberId, Constants.MemberOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(0); // 0=ä¼å |
| | | notice.setUserId(memberId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订å |
| | | notice.setStatus(0); // 0=æªè¯» |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | /** |
| | | * åéé¨åºç«å
ä¿¡éç¥ |
| | | */ |
| | | private void sendShopNotice(Integer shopId, Constants.ShopOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(2); // 2=é¨åº |
| | | notice.setUserId(shopId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订å |
| | | notice.setStatus(0); // 0=æªè¯» |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | @Override |
| | | public Integer create(DriverInfo driverInfo) { |
| | |
| | | .set(DriverInfo::getCardEndDate, request.getCardEndDate()) |
| | | .set(DriverInfo::getIdcardImg, request.getIdcardImg()) |
| | | .set(DriverInfo::getIdcardImgBack, request.getIdcardImgBack()) |
| | | .set(DriverInfo::getAuditStatus, Constants.ZERO) |
| | | .set(DriverInfo::getAliAccount, request.getAliAccount()) |
| | | .set(DriverInfo::getAliName, request.getAliName()) |
| | | .set(DriverInfo::getUpdateTime, now) |
| | | .set(DriverInfo::getAuditRemark, null) |
| | | .set(DriverInfo::getAuditTime, null) |
| | |
| | | log.setCreateTime(new Date()); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogMapper.insert(log); |
| | | |
| | | // éç¥ä¼åï¼å¸æºåæ´ |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.DRIVER_CHANGED, orderId, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void grabOrder(Integer driverId, Integer orderId) { |
| | | // 1. æ ¡éªå¸æº |
| | | DriverInfo driver = driverInfoMapper.selectById(driverId); |
| | | if (driver == null) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "叿ºä¿¡æ¯ä¸åå¨"); |
| | | } |
| | | // 2. æ ¡éªå¸æºæ¥åç¶æ |
| | | if (!Constants.ONE.equals(driver.getAcceptingStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "请å
å¼å¯æ¥åç¶æ"); |
| | | } |
| | | if (!Integer.valueOf(3).equals(driver.getAuditStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "叿ºå®¡æ ¸æªéè¿ææªç¼´çº³æ¼é"); |
| | | } |
| | | if (driver.getDriverLevel() == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "叿ºç级æªè®¾ç½®"); |
| | | } |
| | | |
| | | // 3. æ ¡éªè®¢å |
| | | Orders order = ordersMapper.selectById(orderId); |
| | | if (order == null || Constants.ONE.equals(order.getDeleted())) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "订åä¸åå¨"); |
| | | } |
| | | if (!Constants.ONE.equals(order.getType())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "ä»
å¼å°å¯å订å坿¢å"); |
| | | } |
| | | if (!Constants.TWO.equals(order.getStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "å½å订åç¶æä¸å
许æ¢å"); |
| | | } |
| | | |
| | | // 4. æ ¡éªå¸æºç级 ⥠订åç级 |
| | | if (order.getGoodLevel() != null && driver.getDriverLevel() < order.getGoodLevel()) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "叿ºç级ä¸è¶³ï¼æ æ³æ¢è¯¥è®¢å"); |
| | | } |
| | | |
| | | // 5. ååæ´æ°ï¼å¸¦ status=2 æ¡ä»¶é²æ¢å¹¶åé夿¢å |
| | | Date now = new Date(); |
| | | int rows = ordersMapper.update(new UpdateWrapper<Orders>().lambda() |
| | | .set(Orders::getAcceptDriver, driverId) |
| | | .set(Orders::getAcceptTime, now) |
| | | .set(Orders::getAcceptType, 0) // 0=æå¨æ¢å |
| | | .set(Orders::getStatus, Constants.OrderStatus.accepted.getStatus()) |
| | | .set(Orders::getUpdateTime, now) |
| | | .eq(Orders::getId, orderId) |
| | | .eq(Orders::getStatus, Constants.TWO)); |
| | | if (rows == 0) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "æ¢å失败ï¼è®¢åå·²è¢«æ¢æç¶æå·²åæ´"); |
| | | } |
| | | |
| | | // 6. åå
¥æä½æ¥å¿ |
| | | OrderLog log = new OrderLog(); |
| | | log.setOrderId(orderId); |
| | | log.setTitle("叿ºæ¢å"); |
| | | log.setLogInfo("叿ºã" + driver.getName() + "ãæ¢åæå"); |
| | | log.setObjType(Constants.ORDER_LOG_DRIVER_PICKUP); |
| | | log.setOptUserId(driver.getMemberId()); |
| | | log.setOptUserType(Constants.ONE); |
| | | log.setOrderStatus(Constants.OrderStatus.accepted.getStatus()); |
| | | log.setCreateTime(now); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogMapper.insert(log); |
| | | |
| | | // 7. éç¥ä¼åï¼å¸æºå·²æ¢å |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_GRABBED, orderId, |
| | | "driverName", driver.getName()); |
| | | |
| | | // éç¥åä»¶é¨åºï¼è®¢åå·²æ¢åå¾
åä»¶ |
| | | if (order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.WAIT_PICKUP, orderId, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void confirmPickup(Integer driverId, DriverPickupDTO dto) { |
| | | Integer orderId = dto.getOrderId(); |
| | | |
| | | // 1. æ ¡éªå¸æº |
| | | DriverInfo driver = driverInfoMapper.selectById(driverId); |
| | | if (driver == null) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "叿ºä¿¡æ¯ä¸åå¨"); |
| | | } |
| | | |
| | | // 2. æ ¡éªè®¢å |
| | | Orders order = ordersMapper.selectById(orderId); |
| | | if (order == null || Constants.ONE.equals(order.getDeleted())) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "订åä¸åå¨"); |
| | | } |
| | | if (!Constants.ONE.equals(order.getType())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "ä»
å¼å°å¯åè®¢åæ¯ææ¤æä½"); |
| | | } |
| | | if (!Constants.equalsInteger(order.getStatus(), Constants.OrderStatus.accepted.getStatus())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "å½å订åç¶æä¸å
许å件确认"); |
| | | } |
| | | if (!driverId.equals(order.getAcceptDriver())) { |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "æ ææä½è¯¥è®¢å"); |
| | | } |
| | | |
| | | // 3. ä¿ååä»¶å¾ç |
| | | Date now = new Date(); |
| | | if (dto.getImages() != null && !dto.getImages().isEmpty()) { |
| | | int sortNum = 0; |
| | | for (String url : dto.getImages()) { |
| | | Multifile multifile = new Multifile(); |
| | | multifile.setObjId(orderId); |
| | | multifile.setObjType(Constants.FileType.DRIVER_TAKE.getKey()); |
| | | multifile.setType(Constants.ZERO); |
| | | multifile.setFileurl(url); |
| | | multifile.setIsdeleted(Constants.ZERO); |
| | | multifile.setCreateDate(now); |
| | | multifile.setSortnum(sortNum++); |
| | | multifileMapper.insert(multifile); |
| | | } |
| | | } |
| | | |
| | | // 4. æ´æ°è®¢åç¶æä¸ºæ´¾éä¸(4) |
| | | ordersMapper.update(new UpdateWrapper<Orders>().lambda() |
| | | .set(Orders::getStatus, Constants.OrderStatus.delivering.getStatus()) |
| | | .set(Orders::getUpdateTime, now) |
| | | .eq(Orders::getId, orderId)); |
| | | |
| | | // 5. åå
¥æä½æ¥å¿ |
| | | OrderLog log = new OrderLog(); |
| | | log.setOrderId(orderId); |
| | | log.setTitle("叿ºå®æåä»¶"); |
| | | log.setLogInfo("叿ºã" + driver.getName() + "ã宿åä»¶ï¼å¼å§æ´¾é"); |
| | | log.setObjType(Constants.ORDER_LOG_DRIVER_PICKUP); |
| | | log.setOptUserId(driver.getMemberId()); |
| | | log.setOptUserType(Constants.ONE); |
| | | log.setOrderStatus(Constants.OrderStatus.delivering.getStatus()); |
| | | log.setCreateTime(now); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogMapper.insert(log); |
| | | |
| | | // éç¥ä¼åï¼è®¢åé
éä¸ |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.DELIVERING, orderId, |
| | | "orderNo", order.getCode(), |
| | | "driverName", driver.getName()); |
| | | |
| | | // éç¥åä»¶é¨åºï¼è®¢åé
éä¸ |
| | | if (order.getTakeShopId() != null) { |
| | | sendShopNotice(order.getTakeShopId(), Constants.ShopOrderNotify.DELIVERING, orderId, |
| | | "orderNo", order.getCode(), |
| | | "driverName", driver.getName()); |
| | | } |
| | | } |
| | | |
| | | private List<String> getFileUrls(Integer orderId, int objType, String prefix) { |
| | |
| | | * é¨åºç¨æ·èº«ä»½æ¶ï¼å¡«å
é¨åºå®¡æ ¸ç¶æ |
| | | */ |
| | | private void fillShopInfo(UserCenterVO userCenterVO, Member member) { |
| | | if (Constants.TWO.equals(member.getUserType())) { |
| | | ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getRegionMemberId, member.getId()) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (shopInfo != null) { |
| | | userCenterVO.setShopId(shopInfo.getId()); |
| | | userCenterVO.setShopAuditStatus(shopInfo.getAuditStatus()); |
| | | } |
| | | ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getRegionMemberId, member.getId()) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (shopInfo != null) { |
| | | userCenterVO.setShopId(shopInfo.getId()); |
| | | userCenterVO.setShopAuditStatus(shopInfo.getAuditStatus()); |
| | | } |
| | | // æ ¹æ®openidæ¥è¯¢å½åç»å®çé¨åº |
| | | if (StringUtils.isNotBlank(member.getOpenid())) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.service.business.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.doumee.core.model.PageData; |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.dao.business.NoticeMapper; |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.doumee.service.business.NoticeService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ¶æ¯éç¥ä¿¡æ¯Serviceå®ç° |
| | | * @author rk |
| | | * @date 2026/04/20 |
| | | */ |
| | | @Service |
| | | public class NoticeServiceImpl implements NoticeService { |
| | | |
| | | @Autowired |
| | | private NoticeMapper noticeMapper; |
| | | |
| | | @Override |
| | | public Integer create(Notice notice) { |
| | | noticeMapper.insert(notice); |
| | | return notice.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteById(Integer id) { |
| | | noticeMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(Notice notice) { |
| | | QueryWrapper<Notice> deleteWrapper = new QueryWrapper<>(notice); |
| | | noticeMapper.delete(deleteWrapper); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteByIdInBatch(List<Integer> ids) { |
| | | if (ids == null || ids.isEmpty()) { |
| | | return; |
| | | } |
| | | noticeMapper.deleteBatchIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | public void updateById(Notice notice) { |
| | | noticeMapper.updateById(notice); |
| | | } |
| | | |
| | | @Override |
| | | public void updateByIdInBatch(List<Notice> notices) { |
| | | if (notices == null || notices.isEmpty()) { |
| | | return; |
| | | } |
| | | for (Notice notice : notices) { |
| | | this.updateById(notice); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Notice findById(Integer id) { |
| | | return noticeMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public Notice findOne(Notice notice) { |
| | | QueryWrapper<Notice> wrapper = new QueryWrapper<>(notice); |
| | | return noticeMapper.selectOne(wrapper); |
| | | } |
| | | |
| | | @Override |
| | | public List<Notice> findList(Notice notice) { |
| | | QueryWrapper<Notice> wrapper = new QueryWrapper<>(notice); |
| | | return noticeMapper.selectList(wrapper); |
| | | } |
| | | |
| | | @Override |
| | | public PageData<Notice> findPage(PageWrap<Notice> pageWrap) { |
| | | IPage<Notice> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); |
| | | QueryWrapper<Notice> queryWrapper = new QueryWrapper<>(); |
| | | if (pageWrap.getModel() != null) { |
| | | if (pageWrap.getModel().getIsdeleted() != null) { |
| | | queryWrapper.lambda().eq(Notice::getIsdeleted, pageWrap.getModel().getIsdeleted()); |
| | | } |
| | | if (pageWrap.getModel().getUserType() != null) { |
| | | queryWrapper.lambda().eq(Notice::getUserType, pageWrap.getModel().getUserType()); |
| | | } |
| | | if (pageWrap.getModel().getUserId() != null) { |
| | | queryWrapper.lambda().eq(Notice::getUserId, pageWrap.getModel().getUserId()); |
| | | } |
| | | if (pageWrap.getModel().getObjType() != null) { |
| | | queryWrapper.lambda().eq(Notice::getObjType, pageWrap.getModel().getObjType()); |
| | | } |
| | | if (pageWrap.getModel().getStatus() != null) { |
| | | queryWrapper.lambda().eq(Notice::getStatus, pageWrap.getModel().getStatus()); |
| | | } |
| | | if (pageWrap.getModel().getTitle() != null) { |
| | | queryWrapper.lambda().like(Notice::getTitle, pageWrap.getModel().getTitle()); |
| | | } |
| | | if (pageWrap.getModel().getCreateDate() != null) { |
| | | queryWrapper.lambda().ge(Notice::getCreateDate, pageWrap.getModel().getCreateDate()); |
| | | } |
| | | } |
| | | for (PageWrap.SortData sortData : pageWrap.getSorts()) { |
| | | if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { |
| | | queryWrapper.orderByDesc(sortData.getProperty()); |
| | | } else { |
| | | queryWrapper.orderByAsc(sortData.getProperty()); |
| | | } |
| | | } |
| | | return PageData.from(noticeMapper.selectPage(page, queryWrapper)); |
| | | } |
| | | |
| | | @Override |
| | | public long count(Notice notice) { |
| | | QueryWrapper<Notice> wrapper = new QueryWrapper<>(notice); |
| | | return noticeMapper.selectCount(wrapper); |
| | | } |
| | | } |
| | |
| | | import com.doumee.biz.system.OperationConfigBiz; |
| | | import com.doumee.biz.system.SystemDictDataBiz; |
| | | import com.doumee.config.wx.WxMiniConfig; |
| | | import com.doumee.config.wx.WxMiniUtilService; |
| | | import com.doumee.config.wx.WxPayProperties; |
| | | import com.doumee.config.wx.WxPayV3Service; |
| | | import com.wechat.pay.java.service.refund.model.Refund; |
| | | import com.doumee.core.constants.Constants; |
| | | import com.doumee.core.constants.ResponseStatus; |
| | | import com.doumee.core.exception.BusinessException; |
| | | import com.doumee.core.model.PageData; |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.core.utils.DateUtil; |
| | | import com.doumee.core.utils.Tencent.MapUtil; |
| | | import com.doumee.core.utils.geocode.MapUtil; |
| | | import com.doumee.core.utils.Utils; |
| | | import com.doumee.dao.business.*; |
| | | import com.doumee.dao.business.model.*; |
| | |
| | | import com.doumee.dao.dto.MyOrderDTO; |
| | | import com.doumee.dao.dto.OrderItemDTO; |
| | | import com.doumee.dao.vo.*; |
| | | import com.doumee.service.business.NoticeService; |
| | | import com.doumee.service.business.OrderLogService; |
| | | import com.doumee.service.business.OrdersService; |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.doumee.service.business.AreasService; |
| | | import com.doumee.service.business.PricingRuleService; |
| | | import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; |
| | | import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; |
| | | import com.github.binarywang.wxpay.exception.WxPayException; |
| | | import com.github.xiaoymin.knife4j.core.util.CollectionUtils; |
| | |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.net.InetAddress; |
| | | import java.net.UnknownHostException; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * å¯å订åä¿¡æ¯Serviceå®ç° |
| | |
| | | @Autowired |
| | | private RevenueMapper revenueMapper; |
| | | |
| | | @Autowired |
| | | private WxMiniUtilService wxMiniUtilService; |
| | | |
| | | |
| | | @Autowired |
| | | private SystemUserMapper systemUserMapper; |
| | |
| | | |
| | | @Autowired |
| | | private AreasService areasService; |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | @Autowired |
| | | private WxPayV3Service wxPayV3Service; |
| | | |
| | | @Autowired |
| | | private WxPayProperties wxPayProperties; |
| | | |
| | | @Override |
| | | public Integer create(Orders orders) { |
| | |
| | | // 1. è°ç¨è
¾è®¯å°å¾è·ç¦»ç©éµAPI计ç®é©¾è½¦è·ç¦» |
| | | String from = dto.getFromLat() + "," + dto.getFromLgt(); |
| | | String to = dto.getToLat() + "," + dto.getToLgt(); |
| | | JSONObject distanceResult = MapUtil.distanceSingle("driving", from, to); |
| | | JSONObject distanceResult = MapUtil.direction("driving", from, to); |
| | | BigDecimal distance = distanceResult.getBigDecimal("distance"); |
| | | // distance åä½ä¸ºç±³ï¼è½¬ä¸ºå
Ž |
| | | BigDecimal distanceKm = distance.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); |
| | |
| | | |
| | | // 5. å æ¥è´¹ç¨ï¼ç©åä»·æ ¼ Ã å æ¥ç³»æ°(åå
¸ URGENT_COEFFICIENT) |
| | | long urgentFeeFen = 0L; |
| | | if (Boolean.TRUE.equals(dto.getUrgent())) { |
| | | String urgentRateStr = systemDictDataBiz.queryByCode( |
| | | Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode(); |
| | | BigDecimal urgentRate = new BigDecimal(urgentRateStr); |
| | | urgentFeeFen = new BigDecimal(itemPriceTotal).multiply(urgentRate) |
| | | .setScale(0, RoundingMode.HALF_UP).longValue(); |
| | | } |
| | | String urgentRateStr = systemDictDataBiz.queryByCode( |
| | | Constants.OPERATION_CONFIG, Constants.OP_URGENT_COEFFICIENT).getCode(); |
| | | BigDecimal urgentRate = new BigDecimal(urgentRateStr); |
| | | urgentFeeFen = new BigDecimal(itemPriceTotal).multiply(urgentRate) |
| | | .setScale(0, RoundingMode.HALF_UP).longValue(); |
| | | |
| | | // 6. æ»ä»·æ ¼ = ç©åä»·æ ¼ + ä¿ä»·è´¹ç¨ + å æ¥è´¹ç¨ |
| | | long totalPrice = itemPriceTotal + insuranceFeeFen + urgentFeeFen; |
| | | // 6. æ»ä»·æ ¼ = ç©åä»·æ ¼ + ä¿ä»·è´¹ç¨ + å æ¥è´¹ç¨ï¼å æ¥æ¶æå
å«å æ¥è´¹ï¼ |
| | | long totalPrice = itemPriceTotal + insuranceFeeFen; |
| | | if (Boolean.TRUE.equals(dto.getUrgent())) { |
| | | totalPrice += urgentFeeFen; |
| | | } |
| | | |
| | | PriceCalculateVO result = new PriceCalculateVO(); |
| | | result.setItemList(itemList); |
| | |
| | | takeLocationValue = takeShop.getAddress(); |
| | | } else if (dto.getTakeLat() != null && dto.getTakeLgt() != null && StringUtils.isNotBlank(dto.getTakeLocation())) { |
| | | // æ åä»¶é¨åºï¼æ ¡éªåä»¶ç¹ä¸èªéåä»¶ç¹æ¯å¦å¨åä¸åå¸ |
| | | if (MapUtil.isSameCity(depositShop.getLatitude(), depositShop.getLongitude(), |
| | | if (!MapUtil.isSameCity(depositShop.getLatitude(), depositShop.getLongitude(), |
| | | dto.getTakeLat().doubleValue(), dto.getTakeLgt().doubleValue())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "å¼å°å¯å订åååç¹ä¸è½å¨åä¸åå¸ï¼å¦éååå¯åè¯·éæ©å°±è¿é¨åº"); |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "å¼å°å¯å订åååç¹ä¸å¨åä¸åå¸ï¼å¦éè¯·éæ©ååé¨åº"); |
| | | } |
| | | takeLat = dto.getTakeLat(); |
| | | takeLgt = dto.getTakeLgt(); |
| | |
| | | if (member == null || StringUtils.isBlank(member.getOpenid())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "ç¨æ·ä¿¡æ¯å¼å¸¸ï¼æ æ³åèµ·æ¯ä»"); |
| | | } |
| | | PayResponse payResponse = wxPay(orders, member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | PayResponse payResponse = wxPayV3(orders.getOutTradeNo(), orders.getTotalAmount(), orders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | payResponse.setLockKey(lockKey); |
| | | return payResponse; |
| | | } |
| | |
| | | if (member == null || StringUtils.isBlank(member.getOpenid())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "ç¨æ·ä¿¡æ¯å¼å¸¸ï¼æ æ³åèµ·æ¯ä»"); |
| | | } |
| | | return wxPay(orders, member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | return wxPayV3(orders.getOutTradeNo(), orders.getTotalAmount(), orders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.STORAGE_ORDER); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤èµ·å¾®ä¿¡æ¯ä»V3 |
| | | * |
| | | * @param outTradeNo åæ·è®¢åå· |
| | | * @param totalCents æ¯ä»éé¢ï¼åï¼ |
| | | * @param orderId 订åä¸»é® |
| | | * @param openid ç¨æ·å¾®ä¿¡openid |
| | | * @param ordersAttach è®¢åæ¯ä»ç±»å |
| | | * @return PayResponse å
å«å¾®ä¿¡è°èµ·åæ°å订åä¸»é® |
| | | */ |
| | | private PayResponse wxPayV3(String outTradeNo, Long totalCents, Integer orderId, |
| | | String openid, Constants.OrdersAttach ordersAttach) { |
| | | Map<String, String> payParams = wxPayV3Service.createOrder( |
| | | outTradeNo, |
| | | ordersAttach.getName(), |
| | | totalCents != null ? totalCents : 0L, |
| | | openid, |
| | | wxPayProperties.getV3NotifyUrl(), |
| | | ordersAttach.getKey() |
| | | ); |
| | | |
| | | PayResponse payResponse = new PayResponse(); |
| | | payResponse.setResponse(payParams); |
| | | payResponse.setOrderId(orderId); |
| | | return payResponse; |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | // å¯ä»¶é¨åºå æ¯ï¼fieldA=0(ä¼ä¸å¯)/1(个人å¯) |
| | | int depositFieldA = Constants.equalsInteger(depositShop.getCompanyType(), Constants.ONE) ? Constants.ZERO : Constants.ONE; |
| | | BigDecimal depositShopRata = getRevenueShareRata(cityId, depositFieldA); |
| | | // åä»¶é¨åºå æ¯ï¼fieldA=2(ä¼ä¸å)/3(个人å) |
| | | int takeFieldA = Constants.equalsInteger(takeShop.getCompanyType(), Constants.ONE) ? Constants.TWO : Constants.THREE; |
| | | BigDecimal takeShopRata = getRevenueShareRata(cityId, takeFieldA); |
| | | // åä»¶é¨åºå æ¯ï¼æ åä»¶é¨åºæ¶æ¯ä¾ä¸º0 |
| | | BigDecimal takeShopRata = BigDecimal.ZERO; |
| | | if (takeShop != null) { |
| | | int takeFieldA = Constants.equalsInteger(takeShop.getCompanyType(), Constants.ONE) ? Constants.TWO : Constants.THREE; |
| | | takeShopRata = getRevenueShareRata(cityId, takeFieldA); |
| | | } |
| | | |
| | | // 计ç®èªé
¬ï¼åï¼ï¼totalAmount 为åï¼rata 为æ¯ä¾å¼ï¼å¦ 0.15 表示 15%ï¼ |
| | | long driverFee = new BigDecimal(totalAmount).multiply(driverRata).longValue(); |
| | | long depositShopFee = new BigDecimal(totalAmount).multiply(depositShopRata).longValue(); |
| | | long takeShopFee = totalAmount - driverFee - depositShopFee; |
| | | long takeShopFee = new BigDecimal(totalAmount).multiply(takeShopRata).longValue(); |
| | | |
| | | orders.setDriverFee(driverFee); |
| | | orders.setDepositShopFee(depositShopFee); |
| | |
| | | refund.setCreateTime(now); |
| | | refund.setDeleted(Constants.ZERO); |
| | | |
| | | // è°ç¨å¾®ä¿¡é款ï¼å
¨é¢é款 |
| | | String refundCode = wxMiniUtilService.wxRefund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount()); |
| | | refund.setRefundCode(refundCode); |
| | | refund.setRefundTime(new Date()); |
| | | // è°ç¨å¾®ä¿¡é款V3ï¼å
¨é¢é款 |
| | | Refund refundResult = wxPayV3Service.refund(order.getOutTradeNo(), order.getPayAmount(), order.getPayAmount(), |
| | | "订å鿬¾", wxPayProperties.getV3RefundNotifyUrl()); |
| | | refund.setRefundCode(refundResult.getOutRefundNo()); |
| | | refund.setStatus(Constants.ZERO); // 鿬¾ä¸ |
| | | ordersRefundMapper.insert(refund); |
| | | |
| | | order.setStatus(Constants.OrderStatus.cancelled.getStatus()); |
| | |
| | | ordersMapper.updateById(order); |
| | | |
| | | saveCancelLog(order, "ä¼ååæ¶è®¢åï¼å¾
å¯åï¼å
¨é¢é款ï¼", reason, memberId); |
| | | // éç¥ä¼åï¼éæ¬¾ä¸ |
| | | sendOrderNotice(memberId, Constants.MemberOrderNotify.REFUNDING, orderId, |
| | | "orderNo", order.getCode()); |
| | | return; |
| | | } |
| | | |
| | |
| | | order.setCancelTime(now); |
| | | ordersMapper.updateById(order); |
| | | saveCancelLog(order, "ä¼åç³è¯·åæ¶è®¢åï¼å·²å¯å/å·²æ¥åï¼", reason, memberId); |
| | | // éç¥åä»¶é¨åºï¼é款ç³è¯· |
| | | if (order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.REFUNDING, orderId, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | return; |
| | | } |
| | | |
| | |
| | | log.setCreateTime(new Date()); |
| | | log.setDeleted(Constants.ZERO); |
| | | orderLogService.create(log); |
| | | } |
| | | |
| | | /** |
| | | * åé订åç«å
ä¿¡éç¥ |
| | | */ |
| | | private void sendOrderNotice(Integer memberId, Constants.MemberOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(0); // 0=ä¼å |
| | | notice.setUserId(memberId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订å |
| | | notice.setStatus(0); // 0=æªè¯» |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | /** |
| | | * åéé¨åºç«å
ä¿¡éç¥ |
| | | */ |
| | | private void sendShopNotice(Integer shopId, Constants.ShopOrderNotify notify, Integer orderId, String... params) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(2); // 2=é¨åº |
| | | notice.setUserId(shopId); |
| | | notice.setTitle(notify.getTitle()); |
| | | notice.setContent(notify.format(params)); |
| | | notice.setObjId(orderId); |
| | | notice.setObjType(0); // 0=订å |
| | | notice.setStatus(0); // 0=æªè¯» |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | |
| | | /** |
| | | * éç¥åä»¶é¨åºååä»¶é¨åºï¼è®¢å宿/è¯ä»·çï¼ |
| | | */ |
| | | private void notifyBothShops(Orders order, Constants.ShopOrderNotify notify, String... params) { |
| | | if (order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), notify, order.getId(), params); |
| | | } |
| | | if (order.getTakeShopId() != null) { |
| | | sendShopNotice(order.getTakeShopId(), notify, order.getId(), params); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | ordersMapper.updateById(order); |
| | | |
| | | // éç¥ä¼åï¼è®¢åå¾
æ ¸éª |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_VERIFY, order.getId(), |
| | | "orderNo", order.getCode(), |
| | | "storeCode", order.getMemberVerifyCode()); |
| | | |
| | | // å°±å°å¯å订åï¼éç¥åä»¶é¨åºå¾
æ ¸éª |
| | | if (Constants.ZERO.equals(order.getType()) && order.getDepositShopId() != null) { |
| | | sendShopNotice(order.getDepositShopId(), Constants.ShopOrderNotify.WAIT_VERIFY, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | otherOrders.setCreateTime(now); |
| | | otherOrdersMapper.insert(otherOrders); |
| | | |
| | | // 5. å¤èµ·å¾®ä¿¡æ¯ä» |
| | | return wxPayForOtherOrder(otherOrders, member.getOpenid(), Constants.OrdersAttach.OVERDUE_FEE); |
| | | // 5. å¤èµ·å¾®ä¿¡æ¯ä»V3 |
| | | return wxPayV3(otherOrders.getOutTradeNo(), otherOrders.getPayAccount(), otherOrders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.OVERDUE_FEE); |
| | | } |
| | | |
| | | @Override |
| | |
| | | otherOrders.setCreateTime(now); |
| | | otherOrdersMapper.insert(otherOrders); |
| | | |
| | | // 5. å¤èµ·å¾®ä¿¡æ¯ä» |
| | | return wxPayForOtherOrder(otherOrders, member.getOpenid(), Constants.OrdersAttach.SHOP_DEPOSIT); |
| | | // 5. å¤èµ·å¾®ä¿¡æ¯ä»V3 |
| | | return wxPayV3(otherOrders.getOutTradeNo(), otherOrders.getPayAccount(), otherOrders.getId(), |
| | | member.getOpenid(), Constants.OrdersAttach.SHOP_DEPOSIT); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // éç¥ç¸å
³é¨åºï¼è®¢åå·²ç»ç® |
| | | notifyBothShops(order, Constants.ShopOrderNotify.SETTLED, |
| | | "orderNo", order.getCode(), |
| | | "amount", String.valueOf(Constants.getFormatMoney( |
| | | order.getTotalAmount() != null ? order.getTotalAmount() : 0L))); |
| | | } |
| | | } |
| | | |
| | |
| | | if (isRemote && order.getAcceptDriver() != null) { |
| | | updateTargetScore(Constants.THREE, order.getAcceptDriver()); |
| | | } |
| | | |
| | | // éç¥ä¼åï¼è®¢åå·²è¯ä»· |
| | | sendOrderNotice(memberId, Constants.MemberOrderNotify.EVALUATED, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | |
| | | // éç¥åä»¶é¨åºååä»¶é¨åºï¼è®¢åå·²è¯ä»· |
| | | notifyBothShops(order, Constants.ShopOrderNotify.EVALUATED, |
| | | "orderNo", order.getCode()); |
| | | } |
| | | |
| | | /** |
| | |
| | | saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_DEPOSIT.getKey(), shopId); |
| | | // è®°å½è®¢åæ¥å¿ |
| | | saveShopVerifyLog(order, "é¨åºç¡®è®¤å¯å", "é¨åºã" + shopName + "ã确认å¯å", remark, shopId); |
| | | // éç¥ä¼åï¼é¨åºæ ¸éæå |
| | | if (Constants.equalsInteger(order.getType(), Constants.ONE)) { |
| | | // å¼å°å¯å â å¾
æ¢å |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_GRAB, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | } else { |
| | | // å°±å°å¯å â å¾
åä»¶æé |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.WAIT_PICKUP_REMIND, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | } |
| | | } else if (Constants.equalsInteger(status, Constants.OrderStatus.arrived.getStatus())) { |
| | | // å¼å°å¯å + æ åä»¶é¨åº â æ æ³æ ¸éï¼å®¢æ·èªåï¼æ é¨åºæä½ï¼ |
| | | if (Constants.equalsInteger(order.getType(), Constants.ONE) && order.getTakeShopId() == null) { |
| | |
| | | generateRevenueRecords(order.getId()); |
| | | // è®°å½è®¢åæ¥å¿ |
| | | saveShopVerifyLog(order, "é¨åºç¡®è®¤åä»¶", "é¨åºã" + shopName + "ã确认åä»¶ï¼è®¢å宿", remark, shopId); |
| | | // éç¥ä¼åï¼è®¢å已宿 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | // éç¥åä»¶é¨åºååä»¶é¨åºï¼è®¢å已宿 |
| | | String settleDays = operationConfigBiz.getConfig().getSettlementDate(); |
| | | notifyBothShops(order, Constants.ShopOrderNotify.FINISHED, |
| | | "orderNo", order.getCode(), |
| | | "settleDays", settleDays != null ? settleDays : "7"); |
| | | } else { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "å½å订åç¶æä¸å
è®¸æ ¸é"); |
| | | } |
| | |
| | | refundRecord.setDeleted(Constants.ZERO); |
| | | ordersRefundMapper.insert(refundRecord); |
| | | |
| | | // è°ç¨å¾®ä¿¡éæ¬¾ï¼æ¾å¨æåï¼ç¡®ä¿åç½®æä½å
¨é¨æåï¼ |
| | | String refundCode = wxMiniUtilService.wxRefund( |
| | | order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount()); |
| | | // è°ç¨å¾®ä¿¡é款V3ï¼æ¾å¨æåï¼ç¡®ä¿åç½®æä½å
¨é¨æåï¼ |
| | | Refund refundResult = wxPayV3Service.refund( |
| | | order.getOutTradeNo(), order.getPayAmount(), order.getRefundAmount(), |
| | | "订å鿬¾", wxPayProperties.getV3RefundNotifyUrl()); |
| | | |
| | | // 鿬¾æååå填鿬¾åå·åæ¶é´ |
| | | refundRecord.setRefundCode(refundCode); |
| | | refundRecord.setRefundTime(new Date()); |
| | | // 鿬¾æååå填鿬¾åå·ï¼æ è®°éæ¬¾ä¸ |
| | | refundRecord.setRefundCode(refundResult.getOutRefundNo()); |
| | | refundRecord.setStatus(Constants.ZERO); // 鿬¾ä¸ |
| | | ordersRefundMapper.updateById(refundRecord); |
| | | } |
| | | |
| | |
| | | logInfo += "ï¼é款" + Constants.getFormatMoney(order.getRefundAmount()) + "å
"; |
| | | } |
| | | saveShopVerifyLog(order, "é¨åºç¡®è®¤åºåº", logInfo, remark, shopId); |
| | | // éç¥ä¼åï¼è®¢å已宿 |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.FINISHED, order.getId(), |
| | | "orderNo", order.getCode()); |
| | | // éç¥åä»¶é¨åºååä»¶é¨åºï¼è®¢å已宿 |
| | | String settleDays = operationConfigBiz.getConfig().getSettlementDate(); |
| | | notifyBothShops(order, Constants.ShopOrderNotify.FINISHED, |
| | | "orderNo", order.getCode(), |
| | | "settleDays", settleDays != null ? settleDays : "7"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | // 7. çææ¶çè®°å½ |
| | | calculateAndSaveOrderFees(orderId); |
| | | generateRevenueRecords(orderId); |
| | | |
| | | // éç¥ä¼åï¼è®¢å已宿 |
| | | sendOrderNotice(memberId, Constants.MemberOrderNotify.FINISHED, orderId, |
| | | "orderNo", order.getCode()); |
| | | // éç¥åä»¶é¨åºååä»¶é¨åºï¼è®¢å已宿 |
| | | String settleDays = operationConfigBiz.getConfig().getSettlementDate(); |
| | | notifyBothShops(order, Constants.ShopOrderNotify.FINISHED, |
| | | "orderNo", order.getCode(), |
| | | "settleDays", settleDays != null ? settleDays : "7"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | // ä¿åéä»¶ï¼obj_type=3 é¨åºå
¥åºå¾çï¼æå¤3å¼ ï¼ |
| | | saveVerifyImages(order.getId(), images, Constants.FileType.ORDER_TAKE.getKey(), driverId); |
| | | |
| | | // éç¥ä¼åï¼è®¢åå·²éè¾¾ |
| | | String destination = order.getTakeShopAddress() != null ? order.getTakeShopAddress() : ""; |
| | | if (order.getMemberVerifyCode() != null) { |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.ARRIVED_HAS_SHOP, order.getId(), |
| | | "orderNo", order.getCode(), |
| | | "destination", destination, |
| | | "pickupCode", order.getMemberVerifyCode()); |
| | | } else { |
| | | sendOrderNotice(order.getMemberId(), Constants.MemberOrderNotify.ARRIVED_NO_SHOP, order.getId(), |
| | | "orderNo", order.getCode(), |
| | | "destination", destination); |
| | | } |
| | | |
| | | // éç¥åä»¶é¨åºï¼è®¢åå·²éè¾¾ |
| | | if (order.getTakeShopId() != null) { |
| | | sendShopNotice(order.getTakeShopId(), Constants.ShopOrderNotify.ARRIVED, order.getId(), |
| | | "orderNo", order.getCode(), |
| | | "destination", destination); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | // è
¾è®¯å°å¾è·ç¦»ç©éµAPI计ç®å®é
è·ç¦» |
| | | String from = fromLat + "," + fromLng; |
| | | String to = toLat + "," + toLng; |
| | | JSONObject distanceResult = MapUtil.distanceSingle("driving", from, to); |
| | | JSONObject distanceResult = MapUtil.direction("driving", from, to); |
| | | |
| | | // è·åè·ç¦»ï¼ç±³ï¼ï¼è½¬å
Ž |
| | | int distanceMeters = distanceResult.getIntValue("distance"); |
| | |
| | | existing.setPassword(encryptedPassword); |
| | | existing.setSalt(salt); |
| | | existing.setAliAccount(request.getAliAccount()); |
| | | existing.setAuditStatus(Constants.ZERO); |
| | | existing.setAliName(request.getAliName()); |
| | | existing.setUpdateTime(now); |
| | | existing.setAuditRemark(null); |
| | | existing.setAuditTime(null); |
| | |
| | | shopInfo.setPassword(encryptedPassword); |
| | | shopInfo.setSalt(salt); |
| | | shopInfo.setAliAccount(request.getAliAccount()); |
| | | shopInfo.setOpenid(member.getOpenid()); |
| | | shopInfo.setAuditStatus(Constants.ZERO); |
| | | shopInfo.setAliName(request.getAliName()); |
| | | shopInfo.setStatus(Constants.ZERO); |
| | | shopInfo.setDeleted(Constants.ZERO); |
| | | shopInfo.setCreateTime(now); |
| | |
| | | shopInfo.setLegalPersonName(request.getLegalPersonName()); |
| | | shopInfo.setLegalPersonPhone(request.getLegalPersonPhone()); |
| | | shopInfo.setLegalPersonCard(request.getLegalPersonCard()); |
| | | shopInfo.setAliAccount(request.getAliAccount()); |
| | | shopInfo.setAliName(request.getAliName()); |
| | | shopInfo.setUpdateTime(now); |
| | | shopInfoMapper.updateById(shopInfo); |
| | | |
| | |
| | | vo.setPayStatus(shopInfo.getPayStatus()); |
| | | vo.setScore(shopInfo.getScore()); |
| | | vo.setCreateTime(shopInfo.getCreateTime()); |
| | | vo.setAliAccount(shopInfo.getAliAccount()); |
| | | vo.setAliName(shopInfo.getAliName()); |
| | | |
| | | // æ¼æ¥å¾çåç¼ |
| | | String imgPrefix = ""; |
| | |
| | | import com.doumee.dao.business.model.ShopInfo; |
| | | import com.doumee.dao.business.model.WithdrawalOrders; |
| | | import com.doumee.dao.dto.WithdrawalApproveDTO; |
| | | import com.doumee.config.alipay.AlipayFundTransUniTransfer; |
| | | import com.doumee.dao.dto.AlipayTransferDTO; |
| | | import com.doumee.dao.dto.WithdrawalDTO; |
| | | import com.doumee.dao.system.SystemUserMapper; |
| | | import com.doumee.dao.system.model.SystemUser; |
| | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.text.SimpleDateFormat; |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void approve(WithdrawalApproveDTO dto) { |
| | | if (dto == null || dto.getId() == null || dto.getStatus() == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "审æ¹åæ°ä¸å®æ´"); |
| | |
| | | Integer currentUserId = getCurrentUserId(); |
| | | Date now = new Date(); |
| | | |
| | | // 审æ¹éè¿æ¶ï¼è°ç¨æ¯ä»å®ææ¬¾ |
| | | Integer finalStatus = dto.getStatus(); |
| | | String doneInfo = null; |
| | | if (Constants.ONE.equals(dto.getStatus())) { |
| | | String aliAccount = order.getAliAccount(); |
| | | String aliName = null; |
| | | |
| | | // ä»å¸æºæé¨åºè·åæ¯ä»å®è´¦æ·åå®åå§å |
| | | if (StringUtils.isBlank(aliAccount)) { |
| | | if (Constants.equalsInteger(order.getMemberType(), Constants.ONE)) { |
| | | DriverInfo driver = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda() |
| | | .eq(DriverInfo::getMemberId, order.getMemberId()) |
| | | .eq(DriverInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (driver != null) { |
| | | aliAccount = driver.getAliAccount(); |
| | | aliName = driver.getAliName(); |
| | | } |
| | | } else if (Constants.equalsInteger(order.getMemberType(), Constants.TWO)) { |
| | | ShopInfo shop = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getRegionMemberId, order.getMemberId()) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (shop != null) { |
| | | aliAccount = shop.getAliAccount(); |
| | | aliName = shop.getAliName(); |
| | | } |
| | | } |
| | | } else { |
| | | // ä» WithdrawalOrders ç aliAccount æ¥å¯¹åºå§å |
| | | if (Constants.equalsInteger(order.getMemberType(), Constants.ONE)) { |
| | | DriverInfo driver = driverInfoMapper.selectOne(new QueryWrapper<DriverInfo>().lambda() |
| | | .eq(DriverInfo::getMemberId, order.getMemberId()) |
| | | .eq(DriverInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (driver != null) { |
| | | aliName = driver.getAliName(); |
| | | } |
| | | } else if (Constants.equalsInteger(order.getMemberType(), Constants.TWO)) { |
| | | ShopInfo shop = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getRegionMemberId, order.getMemberId()) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (shop != null) { |
| | | aliName = shop.getAliName(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (StringUtils.isBlank(aliAccount)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "æ¯ä»å®æç°è´¦æ·æªé
ç½®ï¼æ æ³ææ¬¾"); |
| | | } |
| | | |
| | | // éé¢è½¬æ¢ï¼å â å
|
| | | Long amountFen = order.getAmount() != null ? order.getAmount() : 0L; |
| | | BigDecimal transAmount = new BigDecimal(amountFen).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); |
| | | |
| | | AlipayTransferDTO transferDTO = new AlipayTransferDTO(); |
| | | transferDTO.setOutBizNo(order.getOutBillNo()); |
| | | transferDTO.setTransAmount(transAmount); |
| | | transferDTO.setPayeeAccount(aliAccount); |
| | | transferDTO.setPayeeName(aliName); |
| | | transferDTO.setRemark("æç°ææ¬¾"); |
| | | |
| | | String alipayOrderId; |
| | | try { |
| | | alipayOrderId = AlipayFundTransUniTransfer.transfer(transferDTO); |
| | | } catch (BusinessException e) { |
| | | throw e; |
| | | } catch (Exception e) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "æ¯ä»å®ææ¬¾å¤±è´¥ï¼" + e.getMessage()); |
| | | } |
| | | doneInfo = "æ¯ä»å®è½¬è´¦åå·ï¼" + alipayOrderId; |
| | | } |
| | | |
| | | WithdrawalOrders update = new WithdrawalOrders(); |
| | | update.setId(dto.getId()); |
| | | update.setStatus(dto.getStatus()); |
| | | update.setStatus(finalStatus); |
| | | update.setUserId(currentUserId); |
| | | update.setApproveTime(now); |
| | | update.setApproveRemark(dto.getApproveRemark()); |
| | | update.setUpdateTime(now); |
| | | if (Constants.ONE.equals(finalStatus)) { |
| | | update.setDoneTime(now); |
| | | update.setDoneInfo(doneInfo); |
| | | } else if (doneInfo != null) { |
| | | update.setDoneTime(now); |
| | | update.setDoneInfo(doneInfo); |
| | | } |
| | | withdrawalOrdersMapper.updateById(update); |
| | | |
| | | // æ´æ°å
³èçæç° Revenue è®°å½ç¶æ |
| | |
| | | .eq(Revenue::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (withdrawalRevenue != null) { |
| | | Integer revenueStatus = Constants.ONE.equals(dto.getStatus()) ? Constants.ZERO : Constants.ONE; // éè¿=0æå, 驳å=1失败 |
| | | Integer revenueStatus = Constants.ONE.equals(finalStatus) ? Constants.ZERO : Constants.ONE; // éè¿=0æå, 驳å=1失败 |
| | | revenueMapper.update(new UpdateWrapper<Revenue>().lambda() |
| | | .set(Revenue::getStatus, revenueStatus) |
| | | .set(Revenue::getUpdateTime, now) |
| | | .eq(Revenue::getId, withdrawalRevenue.getId())); |
| | | } |
| | | |
| | | // 驳忶éåä½é¢ |
| | | if (Constants.TWO.equals(dto.getStatus())) { |
| | | // é©³åæææ¬¾å¤±è´¥æ¶éåä½é¢ |
| | | if (Constants.TWO.equals(finalStatus)) { |
| | | Long amountFen = order.getAmount() != null ? order.getAmount() : 0L; |
| | | if (amountFen > 0 && order.getMemberId() != null) { |
| | | if (Constants.equalsInteger(order.getMemberType(), Constants.ONE)) { |
| | |
| | | mchKey: u4TSNtv0wFP7WRfnxBgijYOtRhS9FvlM #åæ·ç§é¥ |
| | | apiV3Key: 7tG4Vk9Zp2L8dXw5Jq0N3hR6yE1sF3cB #apiV3Key |
| | | serialNumer: 3FE90C2F3D40A56E1C51926F31B8A8D22426CCE0 #åæ·è¯ä¹¦åºåå· |
| | | notifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxPayNotify |
| | | refundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxRefundNotify |
| | | publicKeyId: PUB_KEY_ID_0112298170022025071700291836000600 |
| | | pubKeyPath: D:\DouMee\1229817002_20220310_cert\pub_key.pem #åæ·æ¯ä»å
¬é¥ |
| | | keyPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.p12 |
| | | privateCertPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.pem |
| | | privateKeyPath: D:\DouMee\1229817002_20220310_cert\apiclient_key.pem |
| | | pubKeyPath: D:\DouMee\1229817002_20220310_cert\pub_key.pem #åæ·æ¯ä»å
¬é¥ |
| | | notifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxPayNotify |
| | | refundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxRefundNotify |
| | | v3NotifyUrl: http://xiaopiqiu2.natapp1.cc/web/api/wxPayV3Notify |
| | | v3RefundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/api/wxRefundV3Notify |
| | | |
| | | # appId: wx6264b4f3a697cbe8 |
| | | # appSecret: 23734577e8978138c946b727f0394027 |
| | |
| | | # è
¾è®¯å°å¾apikey |
| | | tencent_key: WE3BZ-HN6WS-ONDOH-62QCV-MNL6F-5NFNE |
| | | |
| | | # é«å¾·å°å¾apikey |
| | | geocode_map_key: 9a62636d82d6c7c2372e57d80f99287c |
| | | |
| | | |
| | | |
| | | |
| | |
| | | serialNumer: 3FE90C2F3D40A56E1C51926F31B8A8D22426CCE0 #åæ·è¯ä¹¦åºåå· |
| | | notifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxPayNotify |
| | | refundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/wxRefundNotify |
| | | v3NotifyUrl: http://xiaopiqiu2.natapp1.cc/web/api/wxPayV3Notify |
| | | v3RefundNotifyUrl: http://xiaopiqiu2.natapp1.cc/web/api/wxRefundV3Notify |
| | | keyPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.p12 |
| | | privateCertPath: D:\DouMee\1229817002_20220310_cert\apiclient_cert.pem |
| | | privateKeyPath: D:\DouMee\1229817002_20220310_cert\apiclient_key.pem |
| | |
| | | |
| | | |
| | | # è
¾è®¯å°å¾apikey |
| | | tencent_key: WE3BZ-HN6WS-ONDOH-62QCV-MNL6F-5NFNE |
| | | tencent_key: WE3BZ-HN6WS-ONDOH-62QCV-MNL6F-5NFNE |
| | | |
| | | # é«å¾·å°å¾apikey |
| | | geocode_map_key: |
| | |
| | | #mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S |
| | | notifyUrl: https://test.doumee.cn/jinkuai_admin/web/wxPayNotify |
| | | refundNotifyUrl: https://test.doumee.cn/jinkuai_admin/web/wxRefundNotify |
| | | v3NotifyUrl: https://test.doumee.cn/jinkuai_admin/web/api/wxPayV3Notify |
| | | v3RefundNotifyUrl: https://test.doumee.cn/jinkuai_admin/web/api/wxRefundV3Notify |
| | | keyPath: /usr/local/jars/payFile/apiclient_cert.p12 |
| | | privateCertPath: /usr/local/jars/payFile/apiclient_cert.pem |
| | | privateKeyPath: /usr/local/jars/payFile/apiclient_key.pem |
| | |
| | | |
| | | |
| | | # è
¾è®¯å°å¾apikey |
| | | tencent_key: WE3BZ-HN6WS-ONDOH-62QCV-MNL6F-5NFNE |
| | | tencent_key: WE3BZ-HN6WS-ONDOH-62QCV-MNL6F-5NFNE |
| | | |
| | | # é«å¾·å°å¾apikey |
| | | geocode_map_key: |
| | |
| | | import com.doumee.core.annotation.LoginRequired; |
| | | import com.doumee.core.annotation.trace.Trace; |
| | | import com.doumee.core.model.ApiResponse; |
| | | import com.doumee.core.utils.Tencent.MapUtil; |
| | | import com.doumee.core.utils.geocode.MapUtil; |
| | | import com.doumee.dao.business.model.Areas; |
| | | import com.doumee.dao.business.model.Banner; |
| | | import com.doumee.dao.business.model.Category; |
| | |
| | | import com.doumee.dao.dto.DriverActiveOrderDTO; |
| | | import com.doumee.dao.dto.DriverGrabOrderDTO; |
| | | import com.doumee.dao.dto.DriverLoginRequest; |
| | | import com.doumee.dao.dto.DriverPickupDTO; |
| | | import com.doumee.dao.dto.DriverRegisterRequest; |
| | | import com.doumee.dao.dto.DriverVerifyRequest; |
| | | import com.doumee.dao.vo.AccountResponse; |
| | |
| | | |
| | | @LoginDriverRequired |
| | | @Trace |
| | | @ApiOperation(value = "叿ºæ¢å", notes = "对已å¯å(status=2)çå¼å°å¯å订ååèµ·æ¢å") |
| | | @PostMapping("/grabOrder") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "ç¨æ·tokenå¼", required = true), |
| | | @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "orderId", value = "订å主é®", required = true) |
| | | }) |
| | | public ApiResponse grabOrder(@RequestParam Integer orderId) { |
| | | driverInfoService.grabOrder(this.getDriverId(), orderId); |
| | | return ApiResponse.success("æ¢åæå"); |
| | | } |
| | | |
| | | @LoginDriverRequired |
| | | @Trace |
| | | @ApiOperation(value = "叿ºè¿è¡ä¸è®¢å", notes = "æ¥è¯¢å·²æ¢å(status=3)ææ´¾éä¸(status=4)ç订åå表") |
| | | @PostMapping("/activeOrders") |
| | | @ApiImplicitParams({ |
| | |
| | | return ApiResponse.success("åæ¶æå"); |
| | | } |
| | | |
| | | @LoginDriverRequired |
| | | @Trace |
| | | @ApiOperation(value = "叿ºå®æåä»¶", notes = "å·²æ¥å(status=3)æ¶ç¡®è®¤åä»¶ï¼è®¢åè¿å
¥æ´¾éä¸(status=4)") |
| | | @PostMapping("/confirmPickup") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "ç¨æ·tokenå¼", required = true) |
| | | }) |
| | | public ApiResponse confirmPickup(@RequestBody @Valid DriverPickupDTO dto) { |
| | | driverInfoService.confirmPickup(this.getDriverId(), dto); |
| | | return ApiResponse.success("æä½æå"); |
| | | } |
| | | |
| | | } |
| | |
| | | package com.doumee.api.web; |
| | | |
| | | import com.doumee.config.wx.WxMiniConfig; |
| | | import com.doumee.config.wx.WxPayV3Service; |
| | | import com.doumee.core.constants.Constants; |
| | | import com.doumee.core.utils.ID; |
| | | import com.doumee.dao.business.OrdersRefundMapper; |
| | | import com.doumee.dao.business.OrdersMapper; |
| | | import com.doumee.dao.business.model.Notice; |
| | | import com.doumee.dao.business.model.Orders; |
| | | import com.doumee.dao.business.model.OrdersRefund; |
| | | import com.doumee.service.business.NoticeService; |
| | | import com.doumee.service.business.OrdersService; |
| | | import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse; |
| | | import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; |
| | | import com.wechat.pay.java.service.payments.model.Transaction; |
| | | import com.wechat.pay.java.service.refund.model.RefundNotification; |
| | | import com.wechat.pay.java.service.refund.model.Status; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.CrossOrigin; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Date; |
| | | import java.util.Objects; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æ¯ä»åè° |
| | |
| | | @Autowired |
| | | private OrdersService ordersService; |
| | | |
| | | @Autowired |
| | | private WxPayV3Service wxPayV3Service; |
| | | |
| | | @Autowired |
| | | private OrdersRefundMapper ordersRefundMapper; |
| | | |
| | | @Autowired |
| | | private OrdersMapper ordersMapper; |
| | | |
| | | @Autowired |
| | | private NoticeService noticeService; |
| | | |
| | | |
| | | // ==================== V2 åè° ==================== |
| | | |
| | | @PostMapping("/web/api/wxPayNotify") |
| | | public String wxPay_notify(@RequestBody String xmlResult) { |
| | | String wxId = ID.nextGUID(); |
| | | log.info("æ¯ä»åè°ä¿¡æ¯("+wxId+") = > " + xmlResult); |
| | | if (StringUtils.isEmpty(xmlResult)){ |
| | | log.info("V2æ¯ä»åè°ä¿¡æ¯(" + wxId + ") => " + xmlResult); |
| | | if (StringUtils.isEmpty(xmlResult)) { |
| | | return null; |
| | | } |
| | | try { |
| | | WxPayOrderNotifyResult result = WxMiniConfig.wxPayService.parseOrderNotifyResult(xmlResult); |
| | | //èªå®ä¹è®¢åå· |
| | | String outTradeNo = result.getOutTradeNo(); |
| | | //微信订åå· |
| | | String paymentNo = result.getTransactionId(); |
| | | |
| | | |
| | | |
| | | if (Constants.SUCCESS.equals(result.getReturnCode())) { |
| | | // æ¯ä»æå |
| | | switch (result.getAttach()) { |
| | | //å¯å订å |
| | | case "storageOrder": { |
| | | ordersService.handleStorageOrderPayNotify(outTradeNo, paymentNo); |
| | | break; |
| | | } |
| | | //åºéºæ¼é订å |
| | | case "shopDeposit": { |
| | | ordersService.handleShopDepositPayNotify(outTradeNo, paymentNo); |
| | | break; |
| | | } |
| | | //é¾æè´¹ç¨è®¢å |
| | | case "overdueFee": { |
| | | ordersService.handleOverdueFeePayNotify(outTradeNo, paymentNo); |
| | | break; |
| | |
| | | return WxPayNotifyResponse.fail(result.getReturnMsg()); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("微信åè°ç»æå¼å¸¸,å¼å¸¸åå {}", e.getLocalizedMessage()); |
| | | log.error("V2微信åè°ç»æå¼å¸¸,å¼å¸¸åå {}", e.getLocalizedMessage()); |
| | | return WxPayNotifyResponse.fail(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | // ==================== V3 åè° ==================== |
| | | |
| | | /** |
| | | * V3æ¯ä»åè° |
| | | */ |
| | | @PostMapping("/web/api/wxPayV3Notify") |
| | | public Map<String, String> wxPayV3Notify( |
| | | @RequestHeader("Wechatpay-Serial") String serialNumber, |
| | | @RequestHeader("Wechatpay-Timestamp") String timestamp, |
| | | @RequestHeader("Wechatpay-Nonce") String nonce, |
| | | @RequestHeader("Wechatpay-Signature") String signature, |
| | | @RequestBody String body) { |
| | | String wxId = ID.nextGUID(); |
| | | log.info("V3æ¯ä»åè°ä¿¡æ¯({}) => {}", wxId, body); |
| | | try { |
| | | Transaction transaction = wxPayV3Service.parsePayNotify( |
| | | serialNumber, timestamp, nonce, signature, body); |
| | | |
| | | String outTradeNo = transaction.getOutTradeNo(); |
| | | String paymentNo = transaction.getTransactionId(); |
| | | |
| | | if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) { |
| | | String attach = transaction.getAttach(); |
| | | if (StringUtils.isNotBlank(attach)) { |
| | | switch (attach) { |
| | | case "storageOrder": |
| | | ordersService.handleStorageOrderPayNotify(outTradeNo, paymentNo); |
| | | break; |
| | | case "shopDeposit": |
| | | ordersService.handleShopDepositPayNotify(outTradeNo, paymentNo); |
| | | break; |
| | | case "overdueFee": |
| | | ordersService.handleOverdueFeePayNotify(outTradeNo, paymentNo); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | Map<String, String> response = new HashMap<>(); |
| | | response.put("code", "SUCCESS"); |
| | | response.put("message", "å¤çæå"); |
| | | return response; |
| | | } catch (Exception e) { |
| | | log.error("V3æ¯ä»åè°å¼å¸¸,å¼å¸¸åå {}", e.getLocalizedMessage()); |
| | | Map<String, String> response = new HashMap<>(); |
| | | response.put("code", "FAIL"); |
| | | response.put("message", e.getMessage()); |
| | | return response; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * V3鿬¾åè° |
| | | */ |
| | | @PostMapping("/web/api/wxRefundV3Notify") |
| | | public Map<String, String> wxRefundV3Notify( |
| | | @RequestHeader("Wechatpay-Serial") String serialNumber, |
| | | @RequestHeader("Wechatpay-Timestamp") String timestamp, |
| | | @RequestHeader("Wechatpay-Nonce") String nonce, |
| | | @RequestHeader("Wechatpay-Signature") String signature, |
| | | @RequestBody String body) { |
| | | String wxId = ID.nextGUID(); |
| | | log.info("V3鿬¾åè°ä¿¡æ¯({}) => {}", wxId, body); |
| | | try { |
| | | RefundNotification refundNotification = wxPayV3Service.parseRefundNotify( |
| | | serialNumber, timestamp, nonce, signature, body); |
| | | |
| | | log.info("V3鿬¾åè°ç»æ, outTradeNo={}, outRefundNo={}, refundStatus={}", |
| | | refundNotification.getOutTradeNo(), |
| | | refundNotification.getOutRefundNo(), |
| | | refundNotification.getRefundStatus()); |
| | | |
| | | // æ ¹æ®é款åå·æ´æ°é款记å½ç¶æ |
| | | String outRefundNo = refundNotification.getOutRefundNo(); |
| | | OrdersRefund refundRecord = ordersRefundMapper.selectOne( |
| | | new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<OrdersRefund>().lambda() |
| | | .eq(OrdersRefund::getRefundCode, outRefundNo) |
| | | .eq(OrdersRefund::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (refundRecord != null) { |
| | | Status refundStatus = refundNotification.getRefundStatus(); |
| | | if (Status.SUCCESS.equals(refundStatus)) { |
| | | refundRecord.setStatus(Constants.ONE); // 鿬¾æå |
| | | refundRecord.setRefundTime(new java.util.Date()); |
| | | } else if (Status.CLOSED.equals(refundStatus) || Status.ABNORMAL.equals(refundStatus)) { |
| | | refundRecord.setStatus(Constants.TWO); // 鿬¾å¤±è´¥ |
| | | } |
| | | ordersRefundMapper.updateById(refundRecord); |
| | | log.info("鿬¾è®°å½ç¶æå·²æ´æ°, refundRecordId={}, status={}", refundRecord.getId(), refundRecord.getStatus()); |
| | | |
| | | // 鿬¾æå â éç¥ä¼å |
| | | if (Status.SUCCESS.equals(refundStatus) && refundRecord.getOrderId() != null) { |
| | | Orders refundOrder = ordersMapper.selectById(refundRecord.getOrderId()); |
| | | if (refundOrder != null) { |
| | | Notice notice = new Notice(); |
| | | notice.setUserType(0); |
| | | notice.setUserId(refundOrder.getMemberId()); |
| | | notice.setTitle(Constants.MemberOrderNotify.REFUNDED.getTitle()); |
| | | notice.setContent(Constants.MemberOrderNotify.REFUNDED.format( |
| | | "orderNo", refundOrder.getCode(), |
| | | "amount", String.valueOf(Constants.getFormatMoney(refundOrder.getRefundAmount() != null ? refundOrder.getRefundAmount() : 0L)))); |
| | | notice.setObjId(refundOrder.getId()); |
| | | notice.setObjType(0); |
| | | notice.setStatus(0); |
| | | notice.setIsdeleted(Constants.ZERO); |
| | | notice.setCreateDate(new java.util.Date()); |
| | | noticeService.create(notice); |
| | | } |
| | | } |
| | | } |
| | | |
| | | Map<String, String> response = new HashMap<>(); |
| | | response.put("code", "SUCCESS"); |
| | | response.put("message", "å¤çæå"); |
| | | return response; |
| | | } catch (Exception e) { |
| | | log.error("V3鿬¾åè°å¼å¸¸,å¼å¸¸åå {}", e.getLocalizedMessage()); |
| | | Map<String, String> response = new HashMap<>(); |
| | | response.put("code", "FAIL"); |
| | | response.put("message", e.getMessage()); |
| | | return response; |
| | | } |
| | | } |
| | | |
| | | } |