| New file |
| | |
| | | package com.ruoyi.web.controller.api.agent; |
| | | |
| | | |
| | | import cn.afterturn.easypoi.excel.ExcelExportUtil; |
| | | import cn.afterturn.easypoi.excel.entity.ExportParams; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.annotation.Log; |
| | | import com.ruoyi.common.basic.PageInfo; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.WebUtils; |
| | | import com.ruoyi.framework.web.service.TokenService; |
| | | import com.ruoyi.system.dto.TransferOrderDto; |
| | | import com.ruoyi.system.export.TBigGiftPackageOrderExport; |
| | | import com.ruoyi.system.model.*; |
| | | import com.ruoyi.system.query.AppUserListQuery; |
| | | import com.ruoyi.system.query.BigGiftPackageOrderQuery; |
| | | import com.ruoyi.system.query.OrderTransferQuery; |
| | | import com.ruoyi.system.service.*; |
| | | import com.ruoyi.system.vo.TOrderTransferDetailVo; |
| | | import com.ruoyi.system.vo.TOrderTransferVo; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.apache.poi.ss.usermodel.Workbook; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.ServletOutputStream; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.net.URLEncoder; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 大礼包订单 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author xiaochen |
| | | * @since 2025-12-08 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/agent/t-big-gift-package-order") |
| | | @Api(tags = "(嘉视达)供应商大礼包订单") |
| | | @RequiredArgsConstructor(onConstructor_ = @Lazy) |
| | | public class AgentBigGiftPackageOrderController { |
| | | |
| | | private final TBigGiftPackageOrderService tBigGiftPackageOrderService; |
| | | private final TAppUserService tAppUserService; |
| | | private final TCompanyService tCompanyService; |
| | | private final TBigGiftPackageService tBigGiftPackageService; |
| | | |
| | | |
| | | @ApiOperation(value = "大礼包订单列表") |
| | | @PostMapping(value = "/pageList") |
| | | public R<Page<TBigGiftPackageOrder>> pageList(@RequestBody BigGiftPackageOrderQuery query) { |
| | | if (!SecurityUtils.isAgentUser()) { |
| | | throw new ServiceException("请使用经销商/股东帐号访问"); |
| | | } |
| | | Page<TBigGiftPackageOrder> tBigGiftPackageOrderPage = new Page<>(query.getPageNum(), query.getPageSize()); |
| | | query.setCompanyId(SecurityUtils.getLoginUser().getUser().getCompanyId()); |
| | | List<TBigGiftPackageOrder> list = tBigGiftPackageOrderService.pageList(tBigGiftPackageOrderPage, query); |
| | | tBigGiftPackageOrderPage.setRecords(list); |
| | | return R.ok(tBigGiftPackageOrderPage); |
| | | } |
| | | |
| | | @ApiOperation(value = "大礼包订单详情") |
| | | @PostMapping(value = "/detail/{id}") |
| | | public R<TBigGiftPackageOrder> detail(@PathVariable Integer id) { |
| | | if (!SecurityUtils.isAgentUser()) { |
| | | throw new ServiceException("请使用经销商/股东帐号访问"); |
| | | } |
| | | TBigGiftPackageOrder tBigGiftPackageOrder = tBigGiftPackageOrderService.getById(id); |
| | | Integer appUserId = tBigGiftPackageOrder.getAppUserId(); |
| | | TAppUser appUser = tAppUserService.getById(appUserId); |
| | | Integer referrerUserId = appUser.getReferrerUserId(); |
| | | if(referrerUserId!=null){ |
| | | // 上级用户 |
| | | TAppUser lastUser = tAppUserService.getById(referrerUserId); |
| | | if (lastUser != null && lastUser.getUserType()==2){ |
| | | tBigGiftPackageOrder.setSaleName(lastUser.getName()); |
| | | if(lastUser.getReferrerUserId()!=null){ |
| | | // 上上级 |
| | | TAppUser lastLastUser = tAppUserService.getById(lastUser.getReferrerUserId()); |
| | | if (lastLastUser != null && lastLastUser.getUserType()==1){ |
| | | tBigGiftPackageOrder.setPartnerName(lastLastUser.getName()); |
| | | } |
| | | } |
| | | } |
| | | if (lastUser != null && lastUser.getUserType()==1){ |
| | | tBigGiftPackageOrder.setPartnerName(lastUser.getName()); |
| | | } |
| | | } |
| | | Integer bigGiftPackageId = tBigGiftPackageOrder.getBigGiftPackageId(); |
| | | TBigGiftPackage tBigGiftPackage = tBigGiftPackageService.getById(bigGiftPackageId); |
| | | tBigGiftPackageOrder.setBigGiftPackageName(tBigGiftPackage.getName()); |
| | | tBigGiftPackageOrder.setBigGiftPackageCover(tBigGiftPackage.getCoverImage()); |
| | | tBigGiftPackageOrder.setBigGiftPackagePrice(tBigGiftPackage.getTotalPrice()); |
| | | tBigGiftPackageOrder.setBigGiftPackageIntro(tBigGiftPackage.getIntroduction()); |
| | | // 销量 |
| | | long count = tBigGiftPackageOrderService.count(new LambdaQueryWrapper<TBigGiftPackageOrder>().eq(TBigGiftPackageOrder::getBigGiftPackageId, bigGiftPackageId).ne(TBigGiftPackageOrder::getStatus, 5)); |
| | | tBigGiftPackageOrder.setBigGiftPackageSales((int)count); |
| | | |
| | | |
| | | Integer companyId = appUser.getCompanyId(); |
| | | if(companyId!=null){ |
| | | TCompany tCompany = tCompanyService.getById(companyId); |
| | | tBigGiftPackageOrder.setCompanyName(tCompany.getName()); |
| | | } |
| | | return R.ok(tBigGiftPackageOrder); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | package com.ruoyi.web.controller.api.agent; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.BasePage; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.system.model.TCompany; |
| | | import com.ruoyi.system.query.CompanyUserQuery; |
| | | import com.ruoyi.system.query.ProfitPageListQuery; |
| | | import com.ruoyi.system.query.PromotionPageListQuery; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | import com.ruoyi.system.service.TBigGiftPackageOrderService; |
| | | import com.ruoyi.system.service.TCompanyService; |
| | | import com.ruoyi.system.vo.ProfitPageListVo; |
| | | import com.ruoyi.system.vo.PromotionPageListVo; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 经销商管理后台 - 公司信息 前端控制器 |
| | |
| | | public class AgentCompanyController extends BaseController { |
| | | |
| | | private final TCompanyService companyService; |
| | | |
| | | private final ISysUserService userService; |
| | | private final TAppUserService appUserService; |
| | | private final TBigGiftPackageOrderService bigGiftPackageOrderService; |
| | | @ApiOperation(value = "获取当前用户所属公司详情") |
| | | @GetMapping("/detail") |
| | | public R<TCompany> getDetail() { |
| | | // 获取当前登录用户 |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | SysUser user = loginUser.getUser(); |
| | | if (!user.getRoleType().equals(2)) { |
| | | return R.fail("请使用经销商账号访问"); |
| | | if (!SecurityUtils.isAgentUser()) { |
| | | throw new ServiceException("请使用经销商/股东帐号访问"); |
| | | } |
| | | // 获取用户所属公司ID |
| | | Integer companyId = user.getCompanyId(); |
| | |
| | | return R.ok(company); |
| | | } |
| | | |
| | | @ApiOperation(value = "公司详情-管理人员列表") |
| | | @PostMapping(value = "/getCompanyUserList") |
| | | public R<Page<SysUser>> getCompanyUserList(@RequestBody BasePage pageReq) { |
| | | if (!SecurityUtils.isAgentUser()) { |
| | | throw new ServiceException("请使用经销商/股东帐号访问"); |
| | | } |
| | | // 获取当前登录用户 |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Integer companyId = loginUser.getUser().getCompanyId(); |
| | | Page<SysUser> page = new Page<>(pageReq.getPageNum(), pageReq.getPageSize()); |
| | | List<SysUser> list = userService.getCompanyUserList(page,companyId); |
| | | page.setRecords(list); |
| | | return R.ok(page); |
| | | } |
| | | |
| | | @ApiOperation(value = "推广记录") |
| | | @PostMapping("/promotionPageList") |
| | | public R<Page<PromotionPageListVo>> promotionPageList(@RequestBody @Valid PromotionPageListQuery query) { |
| | | if (!SecurityUtils.isAgentUser()) { |
| | | throw new ServiceException("请使用经销商/股东帐号访问"); |
| | | } |
| | | Page<PromotionPageListVo> page = new Page<>(query.getPageNum(), query.getPageSize()); |
| | | query.setCompanyId(SecurityUtils.getLoginUser().getUser().getCompanyId()); |
| | | List<PromotionPageListVo> list = appUserService.promotionPageList(page,query); |
| | | page.setRecords(list); |
| | | return R.ok(page); |
| | | } |
| | | |
| | | @ApiOperation(value = "收益明细") |
| | | @PostMapping("/profitPageList") |
| | | public R<Page<ProfitPageListVo>> profitPageList(@RequestBody @Valid ProfitPageListQuery query) { |
| | | if (!SecurityUtils.isAgentUser()) { |
| | | throw new ServiceException("请使用经销商/股东帐号访问"); |
| | | } |
| | | Page<ProfitPageListVo> page = new Page<>(query.getPageNum(), query.getPageSize()); |
| | | List<ProfitPageListVo> list = bigGiftPackageOrderService.profitPageList(page,query); |
| | | page.setRecords(list); |
| | | return R.ok(page); |
| | | } |
| | | } |
| | |
| | | |
| | | @ApiOperation("根据推广码获取上级用户信息") |
| | | @GetMapping("/getSuperiorInfo") |
| | | public R<SupervisorUserVO> getSuperiorInfo(@ApiParam(name = "superiorType", value = "上级类型 1:股东;2:营销员") |
| | | public R<SupervisorUserVO> getSuperiorInfo(@ApiParam(name = "superiorType", value = "上级类型 1:股东;2:营销员/合伙人") |
| | | @NotNull(message = "上级类型不能为空") @RequestParam Integer superiorType, |
| | | @ApiParam(name = "spreadCode", value = "推广码") |
| | | @NotNull(message = "推广码不能为空") @RequestParam String spreadCode) { |
| | |
| | | boolean success = appletOrderService.confirmBigGiftOrder(id, userId); |
| | | return success ? R.ok() : R.fail("确认收货失败,订单不存在或状态不正确"); |
| | | } |
| | | |
| | | /** |
| | | * 实物商品立即支付(从Redis获取缓存的支付参数) |
| | | * |
| | | * @param id 订单ID |
| | | * @return 支付参数 |
| | | */ |
| | | @ApiOperation(value = "实物商品待支付订单立即支付", response = PlaceOrderVO.class) |
| | | @GetMapping("/physical/pay-now/{id}") |
| | | public R<PlaceOrderVO> physicalPayNow(@PathVariable Integer id) { |
| | | Integer userId = tokenService.getLoginUserApplet().getUserId(); |
| | | PlaceOrderVO result = physicalGoodsOrderService.payNow(id, userId); |
| | | return R.ok(result); |
| | | } |
| | | |
| | | /** |
| | | * 大礼包立即支付(生成新的支付参数) |
| | | * |
| | | * @param id 订单ID |
| | | * @return 支付参数 |
| | | */ |
| | | @ApiOperation(value = "大礼包待支付订单立即支付", response = PlaceOrderVO.class) |
| | | @GetMapping("/big-gift/pay-now/{id}") |
| | | public R<PlaceOrderVO> bigGiftPayNow(@PathVariable Integer id) { |
| | | // 获取当前登录用户 |
| | | Integer userId = tokenService.getLoginUserApplet().getUserId(); |
| | | TAppUser appUser = appUserService.getById(userId); |
| | | if (appUser == null) { |
| | | return R.fail("用户不存在"); |
| | | } |
| | | if (appUser.getOpenid() == null || appUser.getOpenid().isEmpty()) { |
| | | return R.fail("用户未绑定微信"); |
| | | } |
| | | |
| | | PlaceOrderVO result = bigGiftPackageOrderService.payNow(id, userId, appUser.getOpenid()); |
| | | return R.ok(result); |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.common.core.redis.RedisCache; |
| | | import com.ruoyi.common.redis.service.RedisService; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.ip.IpUtils; |
| | | import com.ruoyi.framework.web.service.SysLoginService; |
| | | import com.ruoyi.framework.web.service.SysPermissionService; |
| | | import com.ruoyi.framework.web.service.TokenService; |
| | |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 登录验证 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Slf4j |
| | |
| | | private TAppUserService appUserService; |
| | | |
| | | /** |
| | | * 手机号正则表达式(11位数字,以1开头) |
| | | */ |
| | | private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$"); |
| | | |
| | | /** |
| | | * Redis Key 前缀 |
| | | */ |
| | | private static final String SMS_LIMIT_PHONE_KEY = "sms_limit:phone:"; |
| | | private static final String SMS_LIMIT_PHONE_DAILY_KEY = "sms_limit:phone_daily:"; |
| | | private static final String SMS_LIMIT_IP_KEY = "sms_limit:ip:"; |
| | | private static final String SMS_LIMIT_IP_HOURLY_KEY = "sms_limit:ip_hourly:"; |
| | | |
| | | /** |
| | | * 限制参数 |
| | | */ |
| | | private static final int PHONE_LIMIT_SECONDS = 60; // 手机号60秒限制 |
| | | private static final int PHONE_DAILY_LIMIT = 10; // 手机号每日最多10次 |
| | | private static final int PHONE_DAILY_EXPIRE_HOURS = 24; // 手机号每日限制过期时间 |
| | | private static final int IP_LIMIT_PER_MINUTE = 5; // IP每分钟最多5次 |
| | | private static final int IP_LIMIT_PER_HOUR = 20; // IP每小时最多20次 |
| | | |
| | | /** |
| | | * 获取验证码 |
| | | * |
| | | * @param phone 手机号 |
| | |
| | | @GetMapping("/getCode") |
| | | public AjaxResult getCode(@RequestParam String phone) |
| | | { |
| | | // 发送验证码并存储到redis |
| | | if (StringUtils.hasLength(phone)) { |
| | | |
| | | String code = String.valueOf((int) (Math.random() * 1000000)); |
| | | redisCache.setCacheObject(phone, code,5*60, TimeUnit.SECONDS); |
| | | try { |
| | | //TODO 待对接 |
| | | // smsUtil.sendSms(phone, "2369926", new String[]{code}); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | return AjaxResult.success("发送短信验证码成功!5分钟内有效"); |
| | | // 1. 校验手机号格式 |
| | | if (!StringUtils.hasLength(phone) || !PHONE_PATTERN.matcher(phone).matches()) { |
| | | return AjaxResult.error(500, "手机号格式不正确"); |
| | | } |
| | | return AjaxResult.error(500, "发送短信验证码失败,请确认手机号码!"); |
| | | |
| | | // 2. 获取客户端IP |
| | | String clientIp = IpUtils.getIpAddr(); |
| | | |
| | | // 3. 检查手机号60秒限制 |
| | | String phoneKey = SMS_LIMIT_PHONE_KEY + phone; |
| | | if (redisCache.hasKey(phoneKey)) { |
| | | Long ttl = redisCache.getExpire(phoneKey); |
| | | return AjaxResult.error(500, "请求过于频繁,请" + ttl + "秒后再试"); |
| | | } |
| | | |
| | | // 4. 检查手机号24小时限制 |
| | | String phoneDailyKey = SMS_LIMIT_PHONE_DAILY_KEY + phone; |
| | | Integer phoneDailyCount = redisCache.getCacheObject(phoneDailyKey); |
| | | if (phoneDailyCount != null && phoneDailyCount >= PHONE_DAILY_LIMIT) { |
| | | return AjaxResult.error(500, "该手机号今日获取验证码次数已达上限"); |
| | | } |
| | | |
| | | // 5. 检查IP每分钟限制 |
| | | String ipKey = SMS_LIMIT_IP_KEY + clientIp; |
| | | Integer ipCount = redisCache.getCacheObject(ipKey); |
| | | if (ipCount != null && ipCount >= IP_LIMIT_PER_MINUTE) { |
| | | return AjaxResult.error(500, "请求过于频繁,请稍后再试"); |
| | | } |
| | | |
| | | // 6. 检查IP每小时限制 |
| | | String ipHourlyKey = SMS_LIMIT_IP_HOURLY_KEY + clientIp; |
| | | Integer ipHourlyCount = redisCache.getCacheObject(ipHourlyKey); |
| | | if (ipHourlyCount != null && ipHourlyCount >= IP_LIMIT_PER_HOUR) { |
| | | return AjaxResult.error(500, "请求次数过多,请1小时后再试"); |
| | | } |
| | | |
| | | // 7. 生成并发送验证码 |
| | | String code = String.valueOf((int) (Math.random() * 900000) + 100000); |
| | | redisCache.setCacheObject(phone, code, 5 * 60, TimeUnit.SECONDS); |
| | | try { |
| | | msgUtils.sendMsg(phone, code); |
| | | } catch (Exception e) { |
| | | log.error("发送短信验证码失败,手机号:{},错误:{}", phone, e.getMessage()); |
| | | return AjaxResult.error(500, "发送短信验证码失败,请稍后重试"); |
| | | } |
| | | |
| | | // 8. 更新限制计数器 |
| | | // 手机号60秒限制 |
| | | redisCache.setCacheObject(phoneKey, 1, PHONE_LIMIT_SECONDS, TimeUnit.SECONDS); |
| | | |
| | | // 手机号每日限制 |
| | | if (phoneDailyCount == null) { |
| | | redisCache.setCacheObject(phoneDailyKey, 1, PHONE_DAILY_EXPIRE_HOURS, TimeUnit.HOURS); |
| | | } else { |
| | | redisCache.setCacheObject(phoneDailyKey, phoneDailyCount + 1, PHONE_DAILY_EXPIRE_HOURS, TimeUnit.HOURS); |
| | | } |
| | | |
| | | // IP每分钟限制 |
| | | if (ipCount == null) { |
| | | redisCache.setCacheObject(ipKey, 1, 1, TimeUnit.MINUTES); |
| | | } else { |
| | | // 保持原有过期时间 |
| | | Long ipTtl = redisCache.getExpire(ipKey); |
| | | redisCache.setCacheObject(ipKey, ipCount + 1, ipTtl.intValue() > 0 ? ipTtl.intValue() : 60, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | // IP每小时限制 |
| | | if (ipHourlyCount == null) { |
| | | redisCache.setCacheObject(ipHourlyKey, 1, 1, TimeUnit.HOURS); |
| | | } else { |
| | | // 保持原有过期时间 |
| | | Long ipHourlyTtl = redisCache.getExpire(ipHourlyKey); |
| | | redisCache.setCacheObject(ipHourlyKey, ipHourlyCount + 1, ipHourlyTtl.intValue() > 0 ? ipHourlyTtl.intValue() : 3600, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | log.info("验证码发送成功,手机号:{},IP:{}", phone, clientIp); |
| | | return AjaxResult.success("发送短信验证码成功!5分钟内有效"); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Slf4j |
| | | public class MsgUtils { |
| | | |
| | | // @Value("${code.config.accessKeyId}") |
| | | // private String accessKeyId; |
| | | // @Value("${code.config.accessKeySecret}") |
| | | // private String accessKeySecret; |
| | | // @Value("${code.config.signName}") |
| | | // private String signName; |
| | | // @Value("${code.config.templateCode}") |
| | | // private String templateCode; |
| | | // @Value("${code.config.signNameTest}") |
| | | // private String signNameTest; |
| | | // @Value("${code.config.templateCodeTest}") |
| | | // private String templateCodeTest; |
| | | // |
| | | // /** |
| | | // * 使用AK&SK初始化账号Client |
| | | // * @param accessKeyId |
| | | // * @param accessKeySecret |
| | | // * @return Client |
| | | // * @throws Exception |
| | | // */ |
| | | // public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception { |
| | | // Config config = new Config() |
| | | // // 您的 AccessKey ID |
| | | // .setAccessKeyId(accessKeyId) |
| | | // // 您的 AccessKey Secret |
| | | // .setAccessKeySecret(accessKeySecret); |
| | | // // 访问的域名 |
| | | // config.endpoint = "dysmsapi.aliyuncs.com"; |
| | | // return new com.aliyun.dysmsapi20170525.Client(config); |
| | | // } |
| | | // |
| | | // public void sendMsg(String phone,String code) throws Exception { |
| | | // com.aliyun.dysmsapi20170525.Client client = MsgUtils.createClient(accessKeyId,accessKeySecret); |
| | | // SendSmsRequest sendSmsRequest = new SendSmsRequest() |
| | | // .setSignName(signName) |
| | | // .setTemplateCode(templateCode) |
| | | // .setPhoneNumbers(phone) |
| | | // .setTemplateParam("{\"code\":\""+code+"\"}"); |
| | | // RuntimeOptions runtime = new RuntimeOptions(); |
| | | // try { |
| | | // // 复制代码运行请自行打印 API 的返回值 |
| | | // SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime); |
| | | // log.info("短信发送成功:{},{}",sendSmsResponse.getBody().getMessage(),sendSmsResponse.getStatusCode()); |
| | | // } catch (TeaException error) { |
| | | // // 如有需要,请打印 error |
| | | // com.aliyun.teautil.Common.assertAsString(error.message); |
| | | // log.info("短信发送失败:{}",error.message); |
| | | // } catch (Exception _error) { |
| | | // TeaException error = new TeaException(_error.getMessage(), _error); |
| | | // // 如有需要,请打印 error |
| | | // com.aliyun.teautil.Common.assertAsString(error.message); |
| | | // log.info("短信发送失败:{}",error.message); |
| | | // } |
| | | // } |
| | | @Value("${code.config.accessKeyId}") |
| | | private String accessKeyId; |
| | | @Value("${code.config.accessKeySecret}") |
| | | private String accessKeySecret; |
| | | @Value("${code.config.signName}") |
| | | private String signName; |
| | | @Value("${code.config.templateCode}") |
| | | private String templateCode; |
| | | @Value("${code.config.signNameTest}") |
| | | private String signNameTest; |
| | | @Value("${code.config.templateCodeTest}") |
| | | private String templateCodeTest; |
| | | |
| | | /** |
| | | * 使用AK&SK初始化账号Client |
| | | * @param accessKeyId |
| | | * @param accessKeySecret |
| | | * @return Client |
| | | * @throws Exception |
| | | */ |
| | | public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception { |
| | | Config config = new Config() |
| | | // 您的 AccessKey ID |
| | | .setAccessKeyId(accessKeyId) |
| | | // 您的 AccessKey Secret |
| | | .setAccessKeySecret(accessKeySecret); |
| | | // 访问的域名 |
| | | config.endpoint = "dysmsapi.aliyuncs.com"; |
| | | return new com.aliyun.dysmsapi20170525.Client(config); |
| | | } |
| | | |
| | | public void sendMsg(String phone,String code) throws Exception { |
| | | com.aliyun.dysmsapi20170525.Client client = MsgUtils.createClient(accessKeyId,accessKeySecret); |
| | | SendSmsRequest sendSmsRequest = new SendSmsRequest() |
| | | .setSignName(signName) |
| | | .setTemplateCode(templateCode) |
| | | .setPhoneNumbers(phone) |
| | | .setTemplateParam("{\"code\":\""+code+"\"}"); |
| | | RuntimeOptions runtime = new RuntimeOptions(); |
| | | try { |
| | | // 复制代码运行请自行打印 API 的返回值 |
| | | SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime); |
| | | log.info("短信发送成功:{},{}",sendSmsResponse.getBody().getMessage(),sendSmsResponse.getStatusCode()); |
| | | } catch (TeaException error) { |
| | | // 如有需要,请打印 error |
| | | com.aliyun.teautil.Common.assertAsString(error.message); |
| | | log.info("短信发送失败:{}",error.message); |
| | | } catch (Exception _error) { |
| | | TeaException error = new TeaException(_error.getMessage(), _error); |
| | | // 如有需要,请打印 error |
| | | com.aliyun.teautil.Common.assertAsString(error.message); |
| | | log.info("短信发送失败:{}",error.message); |
| | | } |
| | | } |
| | | } |
| | |
| | | #OSS及短信配置 |
| | | code: |
| | | config: |
| | | templateCodeTest: "SMS_154950909" |
| | | templateCodeTest: "SMS_327789258" |
| | | signNameTest: "阿里云短信测试" |
| | | accessKeyId: LTAI5tAdba8HtT1C6UqtSxBt |
| | | accessKeySecret: 0SRb6XGkciQDPWn2rYqbJtq2qRMDY8 |
| | | signName: "四川金达通信工程" |
| | | templateCode: "SMS_293985284" |
| | | accessKeyId: LTAI5tPoUG8ayR3efxqqaZg8 |
| | | accessKeySecret: mF3bYUh9J6yP5ecLoCYB2vAWbrYrW4 |
| | | signName: "嘉视达" |
| | | templateCode: "SMS_327789258" |
| | | cos: |
| | | client: |
| | | accessKey: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x |
| | |
| | | conf: |
| | | appId: wx87744e4e4094a829 |
| | | secretId: c322159083d844e63dff458b5e54c4c9 |
| | | #OSS及短信配置 |
| | | code: |
| | | config: |
| | | templateCodeTest: "SMS_327789258" |
| | | signNameTest: "阿里云短信测试" |
| | | accessKeyId: LTAI5tPoUG8ayR3efxqqaZg8 |
| | | accessKeySecret: mF3bYUh9J6yP5ecLoCYB2vAWbrYrW4 |
| | | signName: "嘉视达" |
| | | templateCode: "SMS_327789258" |
| | | payment: |
| | | wx: |
| | | # 微信appid |
| | |
| | | order-refund-url: "https://gw.open.icbc.com.cn/api/cardbusiness/aggregatepay/b2c/online/refundqry/V1" |
| | | |
| | | # 完整的回调通知地址,支付完成后通知商户的URL |
| | | notify-url: "http://221.182.45.100:7890/icbc-notify/" |
| | | notify-url: "https://vwpmxwbhv59i.guyubao.com/icbc-notify" |
| | | |
| | | # 回调方法的路径 |
| | | notify-url-method: "/icbc-notify/" |
| | | notify-url-method: "/icbc-notify" |
| | | |
| | | |
| | | |
| | |
| | | { |
| | | return userId != null && 1L == userId; |
| | | } |
| | | |
| | | /** |
| | | * 是否为供应商用户 |
| | | * @return |
| | | */ |
| | | public static boolean isAgentUser(){ |
| | | return !getLoginUser().getUser().getRoleType().equals(1); |
| | | } |
| | | } |
| | |
| | | throw new ServiceException(MessageUtils.message("user.blocked")); |
| | | } |
| | | } |
| | | if ("test".equals(env) || "dev".equals(env)) { |
| | | if (!code.equals("111111")) { |
| | | log.info("登录用户:{} 短信验证码错误{}", username,code); |
| | | throw new ServiceException("短信验证码错误"); |
| | | } |
| | | if (("test".equals(env) || "dev".equals(env)) && code.equals("111111")) { |
| | | //直接放行 |
| | | } else { |
| | | // 校验验证码 |
| | | Object cacheObject = redisCache.getCacheObject(user.getPhone()); |
| New file |
| | |
| | | package com.ruoyi.system.enums; |
| | | |
| | | import lombok.Getter; |
| | | import lombok.AllArgsConstructor; |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum BigGiftPackageOrderStatusEnum { |
| | | PENDING_PAYMENT(1, "待付款"), |
| | | DEPOSIT_PAID(2, "已付订金"), |
| | | PAID(3, "完成支付"), |
| | | CONFIRM_RECEIPT(4, "确认收货"), |
| | | REFUNDED(5, "已退款"), |
| | | CANCELED(6, "已取消"); |
| | | |
| | | private final Integer code; |
| | | private final String desc; |
| | | |
| | | public static BigGiftPackageOrderStatusEnum getEnumByCode(Integer code) { |
| | | for (BigGiftPackageOrderStatusEnum e : BigGiftPackageOrderStatusEnum.values()) { |
| | | if (e.code.equals(code)) { |
| | | return e; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.enums; |
| | | |
| | | import lombok.Getter; |
| | | import lombok.AllArgsConstructor; |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum PhysicalGoodsOrderStatusEnum { |
| | | PENDING_PAYMENT(1, "待付款"), |
| | | PAID(2, "完成支付"), |
| | | CONFIRM_RECEIPT(3, "确认收货"), |
| | | REFUNDED(4, "已退款"), |
| | | CANCELED(5, "已取消"); |
| | | |
| | | private final Integer code; |
| | | private final String desc; |
| | | |
| | | public static PhysicalGoodsOrderStatusEnum getEnumByCode(Integer code) { |
| | | for (PhysicalGoodsOrderStatusEnum e : PhysicalGoodsOrderStatusEnum.values()) { |
| | | if (e.code.equals(code)) { |
| | | return e; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| | |
| | | @ApiModelProperty(value = "支付金额") |
| | | @TableField("payment_price") |
| | | private BigDecimal paymentPrice; |
| | | |
| | | @ApiModelProperty(value = "订单状态(1=待付款,2=已付订金,3=完成支付,4=确认收货,5=已退款,6=已取消)") |
| | | @TableField("status") |
| | | private Integer status; |
| | |
| | | @TableField("deposit_payment_serial_number") |
| | | private String depositPaymentSerialNumber; |
| | | |
| | | @ApiModelProperty(value = "订金付款第三方流水号") |
| | | @TableField("deposit_payment_third_serial_number") |
| | | private String depositPaymentThirdSerialNumber; |
| | | |
| | | @ApiModelProperty(value = "尾款付款时间") |
| | | @TableField("final_payment_time") |
| | | private LocalDateTime finalPaymentTime; |
| | |
| | | @TableField("final_payment_serial_number") |
| | | private String finalPaymentSerialNumber; |
| | | |
| | | @ApiModelProperty(value = "尾款付款第三方流水号") |
| | | @TableField("final_payment_third_serial_number") |
| | | private String finalPaymentThirdSerialNumber; |
| | | |
| | | @ApiModelProperty(value = "支付订单号(用于工行支付,多订单合并支付时共用同一个支付订单号)") |
| | | @TableField("pay_order_code") |
| | | private String payOrderCode; |
| | |
| | | @ApiModelProperty(value = "1=待付款,2=已付订金,3=完成支付,4=确认收货,5=已退款") |
| | | private Integer status; |
| | | |
| | | |
| | | @ApiModelProperty(value = "公司ID") |
| | | private Integer companyId; |
| | | } |
| | |
| | | private String createTime; |
| | | |
| | | @ApiModelProperty("公司id") |
| | | @NotNull(message = "公司id不能为空") |
| | | private Integer companyId; |
| | | } |
| | |
| | | private String phone; |
| | | |
| | | @ApiModelProperty(value = "公司id") |
| | | @NotNull(message = "公司id不能为空") |
| | | private Integer companyId; |
| | | |
| | | } |
| | |
| | | import com.ruoyi.common.basic.PageInfo; |
| | | import com.ruoyi.common.core.domain.model.LoginUserApplet; |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.model.TCompany; |
| | | import com.ruoyi.system.query.AppUserListQuery; |
| | | import com.ruoyi.system.query.ProfitPageListQuery; |
| | | import com.ruoyi.system.query.PromotionPageListQuery; |
| | |
| | | |
| | | List<UserPromotionPageListVo> userPromotionPageListExport(@Valid UserPromotionPageListQuery query); |
| | | |
| | | /** |
| | | * 获取用户所属公司信息 |
| | | * @param appUserId |
| | | * @return |
| | | */ |
| | | TCompany getUserCompany(Integer appUserId); |
| | | } |
| | |
| | | List<UserProfitPageListVo> profitUserPageListExport(@Valid UserProfitPageListQuery query); |
| | | |
| | | List<TBigGiftPackageOrder> pageOrderListExport(@Valid GoldChangeRecordQuery query); |
| | | |
| | | /** |
| | | * 大礼包立即支付(生成新的支付参数) |
| | | * |
| | | * @param orderId 订单ID |
| | | * @param appUserId 用户ID |
| | | * @param openid 用户微信openid |
| | | * @return 支付参数 |
| | | */ |
| | | PlaceOrderVO payNow(Integer orderId, Integer appUserId, String openid); |
| | | } |
| | |
| | | */ |
| | | PlaceOrderVO placeOrder(PhysicalGoodsPlaceOrderDTO dto, Integer appUserId, String openid); |
| | | |
| | | /** |
| | | * 实物商品立即支付(从Redis获取缓存的支付参数) |
| | | * |
| | | * @param orderId 订单ID |
| | | * @param appUserId 用户ID |
| | | * @return 支付参数 |
| | | */ |
| | | PlaceOrderVO payNow(Integer orderId, Integer appUserId); |
| | | |
| | | } |
| | |
| | | import com.icbc.api.utils.IcbcSignature; |
| | | import com.icbc.api.utils.WebUtils; |
| | | import com.ruoyi.system.config.ICBCConfig; |
| | | import com.ruoyi.system.enums.BigGiftPackageOrderStatusEnum; |
| | | import com.ruoyi.system.enums.PhysicalGoodsOrderStatusEnum; |
| | | import com.ruoyi.system.model.TBigGiftPackageOrder; |
| | | import com.ruoyi.system.model.TPhysicalGoodsOrder; |
| | | import com.ruoyi.system.service.*; |
| | |
| | | String payOrderCode = bizContent.getString("out_trade_no"); |
| | | String returnCode = bizContent.getString("return_code"); |
| | | msgId = bizContent.getString("msg_id"); |
| | | |
| | | String orderId = bizContent.getString("order_id"); |
| | | // 验签 |
| | | if (validateSignature(request, icbcConfig.getNotifyUrlMethod() + "/big-gift/pay-notify")) { |
| | | signResult = true; |
| | |
| | | |
| | | // 处理每个订单 |
| | | for (TBigGiftPackageOrder order : orders) { |
| | | processBigGiftPayment(order); |
| | | processBigGiftPayment(order, orderId); |
| | | } |
| | | } else { |
| | | log.error("支付订单号{}【工商银行】大礼包支付失败,错误信息:{}", payOrderCode, bizContent.getString("return_msg")); |
| | | //更新订单状态为已取消 |
| | | orders.forEach(item->item.setStatus(6)); |
| | | orders.forEach(item->item.setStatus(BigGiftPackageOrderStatusEnum.CANCELED.getCode())); |
| | | bigGiftPackageOrderService.updateBatchById(orders); |
| | | } |
| | | } else { |
| | |
| | | } |
| | | |
| | | // 更新订单状态为"完成支付" |
| | | order.setStatus(3); |
| | | order.setStatus(BigGiftPackageOrderStatusEnum.PAID.getCode()); |
| | | order.setFinalPaymentTime(LocalDateTime.now()); |
| | | order.setFinalPaymentSerialNumber(finalPayOrderCode); |
| | | order.setFinalPaymentThirdSerialNumber(orderId); |
| | | order.setPaymentPrice(order.getPaymentPrice().add(order.getFinalPayment())); |
| | | bigGiftPackageOrderService.updateById(order); |
| | | log.info("订单{}状态更新为完成支付", order.getCode()); |
| | | |
| | |
| | | } |
| | | |
| | | // 更新订单状态为"完成支付" |
| | | order.setStatus(2); |
| | | order.setStatus(PhysicalGoodsOrderStatusEnum.PAID.getCode()); |
| | | order.setPaymentTime(LocalDateTime.now()); |
| | | order.setPaymentSerialNumber(orderId); |
| | | physicalGoodsOrderService.updateById(order); |
| | |
| | | |
| | | } else { |
| | | log.error("订单{}【工商银行】实物商品支付失败,错误信息:{}", orderCode, bizContent.getString("return_msg")); |
| | | order.setStatus(5); |
| | | order.setStatus(PhysicalGoodsOrderStatusEnum.CANCELED.getCode()); |
| | | physicalGoodsOrderService.updateById(order); |
| | | } |
| | | } else { |
| | |
| | | /** |
| | | * 处理大礼包支付(定金或全款) |
| | | */ |
| | | private void processBigGiftPayment(TBigGiftPackageOrder order) { |
| | | private void processBigGiftPayment(TBigGiftPackageOrder order, String orderId) { |
| | | Integer paymentType = order.getPaymentType(); |
| | | |
| | | if (paymentType == 1) { |
| | | // 订金+尾款模式,更新状态为"已付订金" |
| | | order.setStatus(2); |
| | | order.setStatus(BigGiftPackageOrderStatusEnum.DEPOSIT_PAID.getCode()); |
| | | order.setDepositTime(LocalDateTime.now()); |
| | | order.setDepositPaymentSerialNumber(order.getPayOrderCode()); |
| | | order.setDepositPaymentThirdSerialNumber(orderId); |
| | | bigGiftPackageOrderService.updateById(order); |
| | | log.info("订单{}状态更新为已付订金,不计算分佣", order.getCode()); |
| | | } else if (paymentType == 2) { |
| | | // 全款模式,更新状态为"完成支付" |
| | | order.setStatus(3); |
| | | order.setStatus(BigGiftPackageOrderStatusEnum.PAID.getCode()); |
| | | order.setDepositTime(LocalDateTime.now()); |
| | | order.setDepositPaymentSerialNumber(order.getPayOrderCode()); |
| | | order.setDepositPaymentThirdSerialNumber(orderId); |
| | | bigGiftPackageOrderService.updateById(order); |
| | | log.info("订单{}状态更新为完成支付", order.getCode()); |
| | | |
| | |
| | | import com.ruoyi.common.basic.PageInfo; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.core.domain.model.LoginUserApplet; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.system.mapper.TAppUserMapper; |
| | | import com.ruoyi.system.model.*; |
| | | import com.ruoyi.system.query.AppUserListQuery; |
| | |
| | | @Autowired |
| | | private TIntegralSettlementService tIntegralSettlementService; |
| | | |
| | | @Autowired |
| | | private TCompanyService tCompanyService; |
| | | |
| | | @Override |
| | | public PageInfo<TAppUser> pageList(AppUserListQuery query) { |
| | | PageInfo<TAppUser> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | |
| | | log.info("推广员不存在,绑定superiorId={}", superiorId); |
| | | } |
| | | } else { |
| | | if (appUser.getReferrerStatus().equals(1)) { |
| | | if (Objects.isNull(appUser.getReferrerStatus()) || appUser.getReferrerStatus().equals(1)) { |
| | | appUser.setReferrerUserId(superiorId); |
| | | appUser.setReferrerTime(LocalDateTime.now()); |
| | | appUser.setReferrerStatus(1); |
| | | } |
| | | } |
| | | this.updateById(appUser); |
| | |
| | | |
| | | @Override |
| | | public List<PromotionPageListVo> promotionPageList(Page<PromotionPageListVo> page, PromotionPageListQuery query) { |
| | | if (Objects.isNull(query.getCompanyId())) { |
| | | throw new ServiceException("公司ID不能为空"); |
| | | } |
| | | List<PromotionPageListVo> list = this.baseMapper.promotionPageList(page,query); |
| | | |
| | | if (!list.isEmpty()) { |
| | |
| | | List<TAppUser> list = this.baseMapper.exportAppUser(query); |
| | | return list; |
| | | } |
| | | |
| | | @Override |
| | | public TCompany getUserCompany(Integer appUserId) { |
| | | //默认返回空对象 |
| | | TCompany company = new TCompany(); |
| | | TAppUser appUser = this.getById(appUserId); |
| | | if (Objects.nonNull(appUser) && Objects.nonNull(appUser.getCompanyId())) { |
| | | company = tCompanyService.getById(appUser.getCompanyId()); |
| | | } |
| | | return company; |
| | | } |
| | | } |
| | |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | @Override |
| | | public void recordVisit(Integer userId) { |
| | | if (Objects.isNull(userId)) { |
| | | return; |
| | | } |
| | | LocalDate today = LocalDate.now(); |
| | | Long count = this.lambdaQuery() |
| | | .eq(TAppUserVisit::getAppUserId, userId) |
| | |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.system.config.ICBCConfig; |
| | | import com.ruoyi.system.dto.BigGiftPlaceOrderDTO; |
| | | import com.ruoyi.system.enums.BigGiftPackageOrderStatusEnum; |
| | | import com.ruoyi.system.mapper.TBigGiftPackageMapper; |
| | | import com.ruoyi.system.mapper.TCommissionTransactionFlowMapper; |
| | | import com.ruoyi.system.mapper.TBigGiftPackageOrderMapper; |
| | |
| | | import com.ruoyi.system.query.GoldChangeRecordQuery; |
| | | import com.ruoyi.system.query.ProfitPageListQuery; |
| | | import com.ruoyi.system.query.UserProfitPageListQuery; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | import com.ruoyi.system.service.TBigGiftPackageOrderService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.system.service.TCommissionTransactionFlowService; |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | |
| | | @Autowired |
| | | private ICBCConfig icbcConfig; |
| | | |
| | | @Autowired |
| | | private TAppUserService appUserService; |
| | | |
| | | @Override |
| | | public List<TBigGiftPackageOrder> pageList(Page<TBigGiftPackageOrder> tBigGiftPackageOrderPage, BigGiftPackageOrderQuery query) { |
| | |
| | | |
| | | @Override |
| | | public List<ProfitPageListVo> profitPageList(Page<ProfitPageListVo> page, ProfitPageListQuery query) { |
| | | if (Objects.isNull(query.getCompanyId())) { |
| | | throw new ServiceException("公司ID不能为空"); |
| | | } |
| | | String sTime = null; |
| | | String eTime = null; |
| | | if(query.getCreateTime()!=null && !query.getCreateTime().isEmpty()){ |
| | |
| | | List<String> orderCodes = new ArrayList<>(); |
| | | String goodsJson = JSON.toJSONString(bigGiftPackage); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | |
| | | //查询用户所属公司,获取经销商商户号 |
| | | TCompany company = appUserService.getUserCompany(appUserId); |
| | | for (int i = 0; i < dto.getQuantity(); i++) { |
| | | TBigGiftPackageOrder order = new TBigGiftPackageOrder(); |
| | | String orderCode = OrderCodeGenerator.generateBigGiftOrderCode(); |
| | | order.setCode(orderCode); |
| | | order.setCompanyId(company.getId()); |
| | | order.setPayOrderCode(payOrderCode); |
| | | order.setAppUserId(appUserId); |
| | | order.setCreateTime(now); |
| | |
| | | order.setFinalPayment(bigGiftPackage.getTotalPrice().subtract(bigGiftPackage.getDeposit())); |
| | | order.setPaymentType(dto.getPaymentType()); |
| | | order.setEffectDayFlag(dto.getEffectDayFlag()); |
| | | order.setPaymentPrice(dto.getPaymentType().equals(1) ? bigGiftPackage.getDeposit() : bigGiftPackage.getTotalPrice()); |
| | | // 订单状态:1=待付款 |
| | | order.setStatus(1); |
| | | order.setStatus(BigGiftPackageOrderStatusEnum.PENDING_PAYMENT.getCode()); |
| | | order.setDelFlag(0); |
| | | |
| | | orderList.add(order); |
| | |
| | | .map(TBigGiftPackageOrder::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | |
| | | // 8. 调用工行支付 |
| | | log.info("大礼包下单,支付订单号:{},业务订单号:{},支付金额:{},用户ID:{}", payOrderCode, orderCodes, paymentAmount, appUserId); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(payOrderCode, paymentAmount, bigGiftPackage.getName(), openid, |
| | | icbcConfig.getNotifyUrl() + "/big-gift/pay-notify"); |
| | | icbcConfig.getNotifyUrl() + "/big-gift/pay-notify", company.getMerchantNumber(), company.getMerchantOpenid()); |
| | | |
| | | // 9. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | |
| | | |
| | | // 6. 生成尾款支付订单号 |
| | | String finalPayOrderCode = OrderCodeGenerator.generateBigGiftFinalPayOrderCode(); |
| | | |
| | | order.setFinalPaymentSerialNumber(finalPayOrderCode); |
| | | this.updateById(order); |
| | | //查询用户所属公司,获取经销商商户号 |
| | | TCompany company = appUserService.getUserCompany(appUserId); |
| | | // 7. 调用工行支付 |
| | | log.info("大礼包尾款支付,订单ID:{},支付订单号:{},尾款金额:{},用户ID:{}", orderId, finalPayOrderCode, finalPayment, appUserId); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(finalPayOrderCode, finalPayment, "大礼包尾款", openid, |
| | | icbcConfig.getNotifyUrl() + "/big-gift/final-pay-notify"); |
| | | icbcConfig.getNotifyUrl() + "/big-gift/final-pay-notify", company.getMerchantNumber(), company.getMerchantOpenid()); |
| | | |
| | | // 8. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | |
| | | vo.setPaymentParams(paymentParams); |
| | | return vo; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public PlaceOrderVO payNow(Integer orderId, Integer appUserId, String openid) { |
| | | // 1. 查询订单 |
| | | TBigGiftPackageOrder order = this.getById(orderId); |
| | | if (order == null) { |
| | | throw new ServiceException("订单不存在"); |
| | | } |
| | | |
| | | // 2. 校验订单归属 |
| | | if (!order.getAppUserId().equals(appUserId)) { |
| | | throw new ServiceException("无权操作此订单"); |
| | | } |
| | | |
| | | // 3. 校验订单状态(必须是待付款状态) |
| | | if (!BigGiftPackageOrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) { |
| | | throw new ServiceException("订单状态不正确,无法支付"); |
| | | } |
| | | |
| | | // 4. 获取商品信息 |
| | | TBigGiftPackage bigGiftPackage = bigGiftPackageMapper.selectById(order.getBigGiftPackageId()); |
| | | String goodsName = bigGiftPackage != null ? bigGiftPackage.getName() : "大礼包商品"; |
| | | |
| | | // 5. 计算支付金额 |
| | | BigDecimal paymentAmount; |
| | | if (order.getPaymentType() == 1) { |
| | | // 订金+尾款模式,支付订金 |
| | | paymentAmount = order.getDeposit(); |
| | | } else { |
| | | // 全款模式 |
| | | paymentAmount = order.getOrderPrice(); |
| | | } |
| | | |
| | | // 6. 生成新的支付订单号 |
| | | String newPayOrderCode = OrderCodeGenerator.generateBigGiftPayOrderCode(); |
| | | |
| | | // 7. 更新当前订单的 payOrderCode |
| | | order.setPayOrderCode(newPayOrderCode); |
| | | |
| | | this.updateById(order); |
| | | |
| | | //查询用户所属公司,获取经销商商户号 |
| | | TCompany company = appUserService.getUserCompany(appUserId); |
| | | |
| | | // 8. 调用工行支付 |
| | | log.info("大礼包立即支付,订单ID:{},新支付订单号:{},支付金额:{},用户ID:{}", orderId, newPayOrderCode, paymentAmount, appUserId); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(newPayOrderCode, paymentAmount, goodsName, openid, |
| | | icbcConfig.getNotifyUrl() + "/big-gift/pay-notify", company.getMerchantNumber(), company.getMerchantOpenid()); |
| | | |
| | | // 9. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | | vo.setOrderIds(Collections.singletonList(orderId)); |
| | | vo.setOrderCodes(Collections.singletonList(order.getCode())); |
| | | vo.setPaymentParams(paymentParams); |
| | | return vo; |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.system.config.ICBCConfig; |
| | | import com.ruoyi.system.dto.PhysicalGoodsPlaceOrderDTO; |
| | | import com.ruoyi.system.enums.PhysicalGoodsOrderStatusEnum; |
| | | import com.ruoyi.system.mapper.TPhysicalGoodsMapper; |
| | | import com.ruoyi.system.mapper.TPhysicalGoodsOrderMapper; |
| | | import com.ruoyi.system.model.TCompany; |
| | | import com.ruoyi.system.model.TPhysicalGoods; |
| | | import com.ruoyi.system.model.TPhysicalGoodsOrder; |
| | | import com.ruoyi.system.query.BigGiftPackageQuery; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | import com.ruoyi.system.service.TPhysicalGoodsOrderService; |
| | | import com.ruoyi.system.utils.ICBCPayUtil; |
| | | import com.ruoyi.system.utils.OrderCodeGenerator; |
| | | import com.ruoyi.system.vo.PlaceOrderVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | @Autowired |
| | | private ICBCConfig icbcConfig; |
| | | |
| | | @Autowired |
| | | private RedisTemplate redisTemplate; |
| | | |
| | | @Autowired |
| | | private TAppUserService appUserService; |
| | | |
| | | /** |
| | | * 实物商品支付参数 Redis Key 前缀 |
| | | */ |
| | | private static final String PHYSICAL_ORDER_PAY_PARAMS_KEY = "physical_order_pay_params:"; |
| | | |
| | | /** |
| | | * 支付参数缓存过期时间(24小时) |
| | | */ |
| | | private static final long PAY_PARAMS_EXPIRE_HOURS = 60; |
| | | |
| | | @Override |
| | | public Page<TPhysicalGoodsOrder> pageList(BigGiftPackageQuery query) { |
| | |
| | | // 支付方式:1=微信 |
| | | order.setPaymentMethod(1); |
| | | // 订单状态:1=待付款 |
| | | order.setStatus(1); |
| | | order.setStatus(PhysicalGoodsOrderStatusEnum.PENDING_PAYMENT.getCode()); |
| | | order.setDelFlag(0); |
| | | |
| | | //查询用户所属公司,获取经销商商户号 |
| | | TCompany company = appUserService.getUserCompany(appUserId); |
| | | order.setCompanyId(company.getId()); |
| | | this.save(order); |
| | | |
| | | // 3. 更新商品销量 |
| | | Integer currentSales = physicalGoods.getSales() == null ? 0 : physicalGoods.getSales(); |
| | | physicalGoods.setSales(currentSales + 1); |
| | | physicalGoodsMapper.updateById(physicalGoods); |
| | | |
| | | // 4. 调用工行支付 |
| | | log.info("实物商品下单,订单号:{},支付金额:{},用户ID:{}", orderCode, physicalGoods.getTotalPrice(), appUserId); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(orderCode, physicalGoods.getTotalPrice(), physicalGoods.getName(), openid,icbcConfig.getNotifyUrl()+"/physical/pay-notify"); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(orderCode, physicalGoods.getTotalPrice(), physicalGoods.getName(), |
| | | openid,icbcConfig.getNotifyUrl()+"/physical/pay-notify", company.getMerchantNumber(), company.getMerchantOpenid()); |
| | | |
| | | // 5. 构建返回结果 |
| | | // 5. 缓存支付参数到 Redis(用于立即支付) |
| | | String redisKey = PHYSICAL_ORDER_PAY_PARAMS_KEY + order.getId(); |
| | | redisTemplate.opsForValue().set(redisKey, paymentParams.toJSONString(), PAY_PARAMS_EXPIRE_HOURS, TimeUnit.MINUTES); |
| | | log.info("实物商品支付参数已缓存,订单ID:{},Redis Key:{}", order.getId(), redisKey); |
| | | |
| | | // 6. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | | vo.setOrderIds(Collections.singletonList(order.getId())); |
| | | vo.setOrderCodes(Collections.singletonList(orderCode)); |
| | | vo.setPaymentParams(paymentParams); |
| | | return vo; |
| | | } |
| | | |
| | | @Override |
| | | public PlaceOrderVO payNow(Integer orderId, Integer appUserId) { |
| | | // 1. 查询订单 |
| | | TPhysicalGoodsOrder order = this.getById(orderId); |
| | | if (order == null) { |
| | | throw new ServiceException("订单不存在"); |
| | | } |
| | | |
| | | // 2. 校验订单所属用户 |
| | | if (!order.getAppUserId().equals(appUserId)) { |
| | | throw new ServiceException("无权操作此订单"); |
| | | } |
| | | |
| | | // 3. 校验订单状态(必须是待付款) |
| | | if (!PhysicalGoodsOrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) { |
| | | throw new ServiceException("订单状态不正确,无法支付"); |
| | | } |
| | | |
| | | // 4. 从 Redis 获取缓存的支付参数 |
| | | String redisKey = PHYSICAL_ORDER_PAY_PARAMS_KEY + orderId; |
| | | Object cachedParams = redisTemplate.opsForValue().get(redisKey); |
| | | if (cachedParams == null) { |
| | | throw new ServiceException("支付参数已过期,请重新下单"); |
| | | } |
| | | |
| | | // 5. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | | vo.setOrderIds(Collections.singletonList(order.getId())); |
| | | vo.setOrderCodes(Collections.singletonList(order.getCode())); |
| | | vo.setPaymentParams(JSON.parseObject(cachedParams.toString())); |
| | | |
| | | log.info("实物商品立即支付,订单ID:{},用户ID:{}", orderId, appUserId); |
| | | return vo; |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.system.config.ICBCConfig; |
| | | import com.ruoyi.system.enums.ICBCRespOrderErrorEnum; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | |
| | | @Autowired |
| | | private ICBCConfig icbcConfig; |
| | | |
| | | public JSONObject wechatPay(String outTradeNo, BigDecimal totalPrice, String goodsName,String openid, String notifyUrl){ |
| | | public JSONObject wechatPay(String outTradeNo, BigDecimal totalPrice, String goodsName,String openid, String notifyUrl, String merId, String merPrtclNo){ |
| | | CardbusinessAggregatepayB2cOnlineConsumepurchaseRequestV1.CardbusinessAggregatepayB2cOnlineConsumepurchaseRequestV1Biz bizContent = new |
| | | CardbusinessAggregatepayB2cOnlineConsumepurchaseRequestV1.CardbusinessAggregatepayB2cOnlineConsumepurchaseRequestV1Biz(); |
| | | bizContent.setMer_id(icbcConfig.getMerId()); |
| | | bizContent.setMer_prtcl_no(icbcConfig.getMerPrtclNo()); |
| | | bizContent.setMer_id(StringUtils.isBlank(merId) ? icbcConfig.getMerId() : merId); |
| | | bizContent.setMer_prtcl_no(StringUtils.isBlank(merPrtclNo) ? icbcConfig.getMerPrtclNo() : merPrtclNo); |
| | | bizContent.setDecive_info(icbcConfig.getDeciveInfo()); |
| | | bizContent.setOut_trade_no(outTradeNo); |
| | | bizContent.setOrig_date_time(DateUtils.getCurrentDateTimeWithT()); |
| | |
| | | package com.ruoyi.system.utils.wx; |
| | | |
| | | import cn.hutool.http.HttpRequest; |
| | | import cn.hutool.http.HttpResponse; |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.icbc.api.internal.util.internal.util.fastjson.JSON; |
| | |
| | | t1.deposit_payment_serial_number, t1.final_payment_time, t1.final_payment_method, |
| | | t1.final_payment_serial_number, t1.del_flag, t1.remark,t2.phone,t2.name userName |
| | | FROM t_big_gift_package_order t1 LEFT JOIN t_app_user t2 ON t1.app_user_id = t2.id |
| | | WHERE t1.del_flag = 0 |
| | | WHERE t1.del_flag = 0 t1.status != 6 |
| | | <if test="query.phone != null and query.phone != ''"> |
| | | AND t2.phone = #{query.phone} |
| | | </if> |
| | |
| | | <if test="sTime !=null "> |
| | | AND t1.create_time BETWEEN #{sTime} AND #{eTime} |
| | | </if> |
| | | <if test="query.companyId != null"> |
| | | AND t1.company_id = #{query.companyId} |
| | | </if> |
| | | order by t1.create_time desc |
| | | </select> |
| | | <select id="export" resultType="com.ruoyi.system.model.TBigGiftPackageOrder"> |