ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/UserPointFallbackFactory.java
New file @@ -0,0 +1,50 @@ package com.ruoyi.account.api.factory; import com.ruoyi.account.api.feignClient.UserPointClient; import com.ruoyi.account.api.model.UserPoint; import com.ruoyi.account.api.model.UserPointCopy; import com.ruoyi.common.core.domain.R; import org.springframework.cloud.openfeign.FallbackFactory; import java.util.List; /** * @author zhibing.pu * @Date 2024/12/2 15:04 */ public class UserPointFallbackFactory implements FallbackFactory<UserPointClient> { @Override public UserPointClient create(Throwable cause) { return new UserPointClient() { @Override public R saveUserPoint(UserPoint userPoint) { return R.fail("保存积分流水记录失败:" + cause.getMessage()); } @Override public R saveUserPointCopy(UserPointCopy userPoint) { return R.fail("保存积分流水记录失败:" + cause.getMessage()); } @Override public R deleteUserPointCopy(Long id, List<Integer> type) { return R.fail("删除积分流水记录失败:" + cause.getMessage()); } @Override public R<List<UserPointCopy>> getUserPointCopy(Long orderId, List<Integer> type) { return R.fail("查询积分流水记录失败:" + cause.getMessage()); } @Override public R<List<UserPoint>> getUserPointList(UserPoint userPoint) { return R.fail("获取积分变动明细失败:" + cause.getMessage()); } @Override public R<Boolean> judgmentDailyShare(Long appUserId) { return R.fail("判断当天是否分享获得过积分失败:" + cause.getMessage()); } }; } } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/UserPointClient.java
New file @@ -0,0 +1,57 @@ package com.ruoyi.account.api.feignClient; import com.ruoyi.account.api.factory.UserPointFallbackFactory; import com.ruoyi.account.api.model.UserPoint; import com.ruoyi.account.api.model.UserPointCopy; import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.domain.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; /** * @author zhibing.pu * @Date 2024/12/2 15:04 */ @FeignClient(contextId = "UserPointClient", value = ServiceNameConstants.ACCOUNT_SERVICE, fallbackFactory = UserPointFallbackFactory.class) public interface UserPointClient { /** * 保存积分流水记录 * @param userPoint * @return */ @PostMapping("/user-point/saveUserPoint") R saveUserPoint(@RequestBody UserPoint userPoint); @PostMapping("/user-point/saveUserPointCopy") R saveUserPointCopy(@RequestBody UserPointCopy userPoint); @DeleteMapping("/user-point/deleteUserPointCopy") R deleteUserPointCopy(@RequestParam("orderId") Long orderId, @RequestParam("type") List<Integer> type); @PostMapping("/user-point/getUserPointCopy") R<List<UserPointCopy>> getUserPointCopy(@RequestParam("orderId") Long orderId, @RequestParam("type") List<Integer> type); /** * 获取积分变动明细 * @param userPoint * @return */ @PostMapping("/user-point/getUserPointList") R<List<UserPoint>> getUserPointList(@RequestBody UserPoint userPoint); /** * 判断当天是否分享获得过积分 * @param appUserId * @return */ @PostMapping("/user-point/judgmentDailyShare") R<Boolean> judgmentDailyShare(@RequestParam("appUserId") Long appUserId); } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/UserPointCopy.java
New file @@ -0,0 +1,102 @@ package com.ruoyi.account.api.model; import com.baomidou.mybatisplus.annotation.TableField; 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 lombok.EqualsAndHashCode; import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.time.LocalDateTime; import java.util.List; /** * <p> * * </p> * * @author luodangjia * @since 2024-11-21 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_user_point_copy") @ApiModel(value="UserPoint对象", description="") public class UserPointCopy implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "主键") @TableId("id") private Long id; @ApiModelProperty(value = "变动类型(1-消费,2-返佣,3-拉新,4-每日分享,5-每日签到,6-使用时长, 7-注册积分, 8-门店业绩," + "9-门店返佣,14-下级门店返佣,10-技师业绩,11-兑换商品,12-他人赠送,13-赠与他人,15-兑换券)") @TableField("type") private Integer type; @ApiModelProperty(value = "历史余额") @TableField("historical_point") private Integer historicalPoint; @ApiModelProperty(value = "变动金额") @TableField("variable_point") private Integer variablePoint; @ApiModelProperty(value = "变动后余额") @TableField("balance") private Integer balance; @ApiModelProperty(value = "变动时间") @TableField("create_time") private LocalDateTime createTime; @ApiModelProperty(value = "变动用户id") @TableField("app_user_id") private Long appUserId; @ApiModelProperty(value = "关联对象id") @TableField("object_id") private Long objectId; @ApiModelProperty(value = "拓展字段") @TableField("extention") private String extention; @ApiModelProperty(value = "用户名称") @TableField(exist = false) private String userName; @ApiModelProperty(value = "变动类型 0未变化1增加2减少") @TableField(exist = false) private Integer variableType; @ApiModelProperty(value = "联系电话") @TableField(exist = false) private String phone; @ApiModelProperty(value = "开始时间") @TableField(exist = false) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime startTime; @ApiModelProperty(value = "结束时间") @TableField(exist = false) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime endTime; @TableField(exist = false) private List<Long> userIds; @TableField(exist = false) private Integer pageNum; @TableField(exist = false) private Integer pageSize; } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/model/Order.java
@@ -35,9 +35,7 @@ @TableField("app_user_id") private Long appUserId; @ApiModelProperty(value = "订单类型1服务单2商品") @TableField("order_type") private Integer orderType; @ApiModelProperty(value = "1待发货2待收货3待使用4已完成5已取消6已退款7售后中8已评价") @TableField("order_status") @@ -47,9 +45,6 @@ @TableField("old_order_status") private Integer oldOrderStatus; @ApiModelProperty(value = "是否已分佣: 0-否 1-普通已拥,2-门店已分佣") @TableField("is_commission") private Integer isCommission; @ApiModelProperty(value = "核销时间") @TableField("end_time") @@ -63,9 +58,6 @@ @TableField("after_sale_time") private LocalDateTime afterSaleTime; @ApiModelProperty(value = "技师id") @TableField("technician_id") private Integer technicianId; @ApiModelProperty(value = "订单编号") @TableField("order_number") @@ -87,33 +79,13 @@ @TableField("total_amount") private BigDecimal totalAmount; @ApiModelProperty(value = "满减金额") @TableField("full_reduction_amount") private BigDecimal fullReductionAmount; @ApiModelProperty(value = "代金券抵扣金额") @TableField("money_amount") private BigDecimal moneyAmount; @ApiModelProperty(value = "折扣券抵扣金额") @TableField("discount_amount") private BigDecimal discountAmount; @ApiModelProperty(value = "商品券抵扣总金额") @TableField("good_amount") private BigDecimal goodAmount; @ApiModelProperty(value = "用户优惠券id") @TableField("user_coupon_id") private Long userCouponId; @ApiModelProperty(value = "活动优惠金额") @ApiModelProperty(value = "积分抵扣金额") @TableField("activity_amount") private BigDecimal activityAmount; private BigDecimal pointDeductionAmount; @ApiModelProperty(value = "优惠总金额") @TableField("discount_total_amount") private BigDecimal discountTotalAmount; @ApiModelProperty(value = "实际支付价格") @TableField("payment_amount") @@ -123,73 +95,21 @@ @TableField("point") private Integer point; @ApiModelProperty(value = "1微信,2账户余额,3积分") @ApiModelProperty(value = "1微信,3积分") @TableField("pay_method") private Integer payMethod; @ApiModelProperty(value = "使用的优惠劵json") @TableField("coupon_json") private String couponJson; @ApiModelProperty(value = "订单优惠活动的json快照") @TableField("activity_json") private String activityJson; @ApiModelProperty(value = "运费") @TableField("express_amount") private BigDecimal expressAmount; @ApiModelProperty(value = "1微信,2账户余额") @TableField("express_pay_method") private Integer expressPayMethod; @ApiModelProperty(value = "配送方式(1=自提,2=快递)") @TableField("distribution_mode") private Integer distributionMode; @ApiModelProperty(value = "第三方快递信息") @TableField("express_json") private String expressJson; @ApiModelProperty(value = "第三方快递结果") @TableField("express_result") private String expressResult; @ApiModelProperty(value = "发货省") @TableField("deliver_province") private String deliverProvince; @ApiModelProperty(value = "发货省编号") @TableField("deliver_province_code") private String deliverProvinceCode; @ApiModelProperty(value = "发货市") @TableField("deliver_city") private String deliverCity; @ApiModelProperty(value = "发货市编号") @TableField("deliver_city_code") private String deliverCityCode; @ApiModelProperty(value = "发货区") @TableField("deliver_district") private String deliverDistrict; @ApiModelProperty(value = "发货区编号") @TableField("deliver_district_code") private String deliverDistrictCode; @ApiModelProperty(value = "收货地址信息") @TableField("address_json") private String addressJson; @ApiModelProperty(value = "平台分佣") @TableField("share_amount") private BigDecimal shareAmount; @ApiModelProperty(value = "本单获取的积分") @TableField("get_point") private Integer getPoint; @ApiModelProperty(value = "微信支付号") @TableField("serial_number") ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/model/OrderGood.java
@@ -37,10 +37,6 @@ @TableField("order_id") private Long orderId; @ApiModelProperty(value = "商品券优惠金额") @TableField("good_amount") private BigDecimal goodsCouponAmount; @ApiModelProperty(value = "购买商品的json快照") @TableField("good_json") private String goodJson; @@ -60,54 +56,7 @@ @ApiModelProperty(value = "添加时间") @TableField("create_time") private LocalDateTime createTime; @ApiModelProperty(value = "可获得消费积分") @TableField("earn_spending_points") private Integer earnSpendingPoints; @ApiModelProperty(value = "上级获得分佣金额") @TableField("superior_subcommission") private BigDecimal superiorSubcommission; @ApiModelProperty(value = "上级获得返佣积分") @TableField("superior_rebate_points") private Integer superiorRebatePoints; @ApiModelProperty(value = "获取返佣积分上级类型(1=直推上级,2=直帮上级)") @TableField("superior_type") private String superiorType; @ApiModelProperty(value = "获取分佣金额上级类型(1=直推上级,2=直帮上级)") @TableField("superior_price_type") private String superiorPriceType; @ApiModelProperty(value = "核销门店可获得服务费") @TableField("servuce_shop_charges") private BigDecimal servuceShopCharges; @ApiModelProperty(value = "核销门店可获得服务积分") @TableField("servuce_shop_points") private Integer servuceShopPoints; @ApiModelProperty(value = "技师可获得服务积分") @TableField("technician_points") private Integer technicianPoints; @ApiModelProperty(value = "绑定门店可获得分佣金额") @TableField("bound_shop_charges") private BigDecimal boundShopCharges; @ApiModelProperty(value = "绑定门店可获得返佣积分") @TableField("bound_shop_points") private Integer boundShopPoints; @ApiModelProperty(value = "绑定门店上级门店可获得分佣金额") @TableField("bound_shop_superiors_charges") private BigDecimal boundShopSuperiorsCharges; @ApiModelProperty(value = "绑定门店上级门店可获得返佣积分") @TableField("bound_shop_superiors_points") private Integer boundShopSuperiorsPoints; @ApiModelProperty("购买类型(1=普通商品,2=秒杀商品)") @TableField("type") private Integer type; ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/OrderDetailVO.java
@@ -18,22 +18,10 @@ private Integer orderStatus; @ApiModelProperty(value = "订单商品") private List<OrderGoodsVO> goodsList; private OrderGoodsVO orderGoodsVO; @ApiModelProperty(value = "使用积分") private Integer point; @ApiModelProperty(value = "收货地址id") private Long addressId; @ApiModelProperty(value = "收货联系人") private String recieveName; @ApiModelProperty(value = "收货联系电话") private String recievePhone; @ApiModelProperty(value = "收货地址") private String recieveAddress; @ApiModelProperty(value = "订单编号") private String orderNumber; @@ -44,26 +32,11 @@ @ApiModelProperty(value = "订单总金额") private BigDecimal totalAmount; @ApiModelProperty(value = "优惠券名称") private String couponName; @ApiModelProperty(value = "参与活动名称") private String activityName; @ApiModelProperty(value = "抵扣金额") private BigDecimal couponAmount; @ApiModelProperty(value = "快递费") private BigDecimal expressAmount; @ApiModelProperty(value = "可获得积分") private Integer pointAmount; @ApiModelProperty(value = "积分抵扣金额") private BigDecimal pointDeductionAmount; @ApiModelProperty(value = "实际支付价格") private BigDecimal paymentAmount; @ApiModelProperty(value = "配送方式(1=自提,2=快递)") private Integer distributionMode; @ApiModelProperty(value = "门店名称") private String shopName; @@ -80,19 +53,7 @@ @ApiModelProperty(value = "门店id") private Integer shopId; @ApiModelProperty(value = "技师名称") private String technicianName; @ApiModelProperty(value = "技师id") private Integer technicianId; @ApiModelProperty(value = "预约单id") private String technicianSubscribeId; @ApiModelProperty("核销码BASE64") private String writeOffCode; @ApiModelProperty("最新快递信息") private String express; } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/OrderPayment.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.order.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author zhibing.pu * @Date 2024/11/25 14:33 */ @Data @ApiModel public class OrderPayment { @ApiModelProperty(value = "商品id", required = true) private Integer goodId; @ApiModelProperty(value = "支付方式(1=微信,3=积分)", required = true) private Integer paymentType; @ApiModelProperty(value = "是否使用积分抵扣(0=否,1=是)", required = true) private Integer isPointDeduction; @ApiModelProperty(value = "核销门店id", required = true) private Integer shopId; } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/OrderVO.java
@@ -31,8 +31,5 @@ @ApiModelProperty(value = "实际支付价格") private BigDecimal paymentAmount; @ApiModelProperty(value = "快递费") private BigDecimal expressAmount; } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/ShoppingCartPayment.java
File was deleted ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Goods.java
@@ -40,21 +40,11 @@ @TableField("goods_category_id") private Integer goodsCategoryId; @ApiModelProperty(value = "类型(1=服务商品,2=单品商品)") @TableField("type") private Integer type; @ApiModelProperty(value = "限购数量(-1不限购)") @TableField("purchase_limit") private Integer purchaseLimit; @ApiModelProperty(value = "配送方式(1=自提,2=快递)") @TableField("distribution_mode") private String distributionMode; @ApiModelProperty(value = "指定门店(1=指定,2=所有)") @TableField("appoint_store") private Integer appointStore; @ApiModelProperty(value = "商品简介") @TableField("introduction") @@ -129,7 +119,7 @@ @TableField(exist = false) @ApiModelProperty(value = "指定门店") private List<GoodsShop> goodsShopList; private GoodsShop goodsShop; @TableField(exist = false) private String categoryName; ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java
New file @@ -0,0 +1,109 @@ package com.ruoyi.other.api.domain; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; /** * <p> * * </p> * * @author luodangjia * @since 2024-11-20 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_shop_balance_statement") @ApiModel(value="ShopBalanceStatement对象", description="") public class ShopBalanceStatement implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "主键") @TableId("id") private Long id; @ApiModelProperty(value = "门店id") @TableField("shop_id") private Integer shopId; @ApiModelProperty(value = "门店名称") @TableField(exist = false) @Excel(name = "门店名称") private String shopName; @ApiModelProperty(value = "店长名称") @TableField(exist = false) @Excel(name = "店长姓名") private String shopManagerName; @ApiModelProperty(value = "联系电话") @TableField(exist = false) @Excel(name = "联系电话") private String phone; @ApiModelProperty(value = "变动类型(1=服务商分佣,2=高级服务商分佣,3=核销门店服务费,4=提现)") @TableField("type") @Excel(name = "变更类型",readConverterExp = "1=服务商分佣,2=高级服务商分佣,3=核销门店服务费") private Integer type; @ApiModelProperty(value = "历史余额") @TableField("historical_balance") private BigDecimal historicalBalance; @ApiModelProperty(value = "变动金额") @TableField("variable_amount") private BigDecimal variableAmount; @ApiModelProperty(value = "变动时间") @TableField("create_time") @Excel(name = "变更时间",dateFormat = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; @ApiModelProperty(value = "变动金额") @TableField(exist = false) @Excel(name = "变更数量") private String variableAmountString; @ApiModelProperty(value = "变动后余额") @TableField("balance") private BigDecimal balance; @ApiModelProperty(value = "变动用户id") @TableField("create_user_id") private Long createUserId; @ApiModelProperty(value = "关联对象id") @TableField("object_id") private Long objectId; @ApiModelProperty(value = "开始时间") @TableField(exist = false) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private String startTime; @ApiModelProperty(value = "结束时间") @TableField(exist = false) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private String endTime; @ApiModelProperty(value = "扩展字段") @TableField("extension") private String extension; } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserController.java
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.api.model.*; import com.ruoyi.account.dto.ChangeAppUserInfo; import com.ruoyi.account.mapper.AppUserMapper; import com.ruoyi.account.service.*; import com.ruoyi.account.util.ObsUploadUtil; @@ -25,11 +26,14 @@ import com.ruoyi.order.model.Order; import com.ruoyi.other.api.domain.Shop; import com.ruoyi.other.api.feignClient.ShopClient; import com.ruoyi.system.api.domain.SysConfig; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysConfigClient; import com.ruoyi.system.api.feignClient.SysUserClient; import com.ruoyi.system.api.model.LoginUser; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.annotations.Param; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; @@ -72,6 +76,8 @@ private SysUserClient sysUserClient; @Resource private OrderClient orderClient; @Resource private SysConfigClient sysConfigClient; @Resource private UserCancellationLogService userCancellationLogService; @@ -90,6 +96,15 @@ @ApiOperation(value = "手机号登录") public R<LoginVo> mobileLogin(@RequestBody MobileLogin mobileLogin) { return appUserService.mobileLogin(mobileLogin); } @GetMapping("/logout") @ApiOperation(value = "登出") public R logout() { Long userId = tokenService.getLoginUserApplet().getUserid(); loginout(userId); return R.ok(); } @@ -140,44 +155,6 @@ } /* @ResponseBody @PostMapping("/registerAccount") @ApiOperation(value = "注册新账号") public R<LoginVo> registerAccount(@RequestBody RegisterAccount registerAccount) { return appUserService.registerAccount(registerAccount); }*/ /* @ResponseBody @GetMapping("/getReferrer/{id}") @ApiOperation(value = "获取推荐人信息") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "推荐人id", required = true, dataType = "long") }) public R<String> getReferrer(@PathVariable("id") Long id) { AppUser appUser = appUserService.getById(id); String phone = appUser.getPhone(); phone = phone.substring(0, 3) + "****" + phone.substring(7); return R.ok(appUser.getName() + "-" + phone); } */ @ResponseBody @PostMapping("/info") @ApiOperation(value = "我的资料", tags = {"小程序-个人中心首页-我的资料"}) public R<AppUser> info() { Long userId = tokenService.getLoginUserApplet().getUserid(); AppUser user = appUserService.getById(userId); if(StringUtils.isEmpty(user.getQrCode())){ //获取微信推广二维码 String fileName = UUID.randomUUID() + ".jpg"; String getwxacodeunlimit = weChatUtil.getwxacodeunlimit("pages/start/start", "id=" + user.getId(), EnvVersion.RELEASE, filePath + fileName); user.setQrCode(getwxacodeunlimit); appUserService.updateById(user); } return R.ok(user); } @@ -187,23 +164,28 @@ public R unregis() { Long userId = tokenService.getLoginUserApplet().getUserid(); AppUser user = appUserService.getById(userId); //添加注销记录 UserCancellationLog userCancellationLog = new UserCancellationLog(); userCancellationLog.setAppUserId(user.getId()); userCancellationLog.setVipId(user.getVipId()); userCancellationLogService.save(userCancellationLog); user.setStatus(3); appUserService.updateById(user); List<AppUser> subUserList = appUserService.list(new LambdaQueryWrapper<AppUser>() .eq(AppUser::getInviteUserId, userId)); for (AppUser appUser : subUserList) { Long inviteUserId = user.getInviteUserId(); appUser.setInviteUserId(inviteUserId); } appUserService.updateBatchById(subUserList); return R.ok(); } @ResponseBody @GetMapping("/getServicePhone") @ApiOperation(value = "获取客服电话", tags = {"小程序-个人中心首页-客服"}) public R getServicePhone() { SysConfig data = sysConfigClient.getInfo(7L).getData(); List<String> phoneList = null; if (data != null) { phoneList = Arrays.stream(data.getConfigValue().split(";")) .map(String::trim) // 去除每个号码前后的空格 .filter(s -> !s.isEmpty()) // 过滤空字符串 .collect(Collectors.toList()); } return R.ok(phoneList); } @@ -219,19 +201,13 @@ @GetMapping("/index") @ApiOperation(value = "个人中心首页", tags = {"小程序-个人中心首页"}) public R<AppUser> index() { Long userId = tokenService.getLoginUserApplet().getUserid(); //当前用户信息 AppUser user = appUserService.getById(userId); if(StringUtils.isEmpty(user.getQrCode())){ //获取微信推广二维码 String fileName = UUID.randomUUID() + ".jpg"; String getwxacodeunlimit = weChatUtil.getwxacodeunlimit("pages/start/start", "id=" + user.getId(), EnvVersion.RELEASE, filePath + fileName); user.setQrCode(getwxacodeunlimit); appUserService.updateById(user); } return R.ok(user); } @@ -274,14 +250,18 @@ @GetMapping("/index/change") @PostMapping("/index/change") @ApiOperation(value = "修改个人资料", tags = {"小程序-个人中心首页"}) public R<AppUser> indexchange(String avatar, String name) { public R<AppUser> indexchange(@RequestBody ChangeAppUserInfo changeAppInfo) { Long userId = tokenService.getLoginUserApplet().getUserid(); //当前用户信息 AppUser user = appUserService.getById(userId); user.setName(name); user.setAvatar(avatar); if (null != changeAppInfo.getName()){ user.setName(changeAppInfo.getName()); } if (null != changeAppInfo.getAvatar()){ user.setAvatar(changeAppInfo.getAvatar()); } appUserService.updateById(user); return R.ok(); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/dto/ChangeAppUserInfo.java
New file @@ -0,0 +1,13 @@ package com.ruoyi.account.dto; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class ChangeAppUserInfo { @ApiModelProperty(value = "名称") private String name; @ApiModelProperty(value = "头像") private String avatar; } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.ruoyi.account.api.feignClient.AppUserClient; import com.ruoyi.account.api.model.AppUser; import com.ruoyi.common.core.constant.ExpressCompanyMap; @@ -20,6 +19,7 @@ import com.ruoyi.order.model.Order; import com.ruoyi.order.service.OrderService; import com.ruoyi.order.util.payment.model.RefundCallbackResult; import com.ruoyi.order.util.payment.model.UniPayCallbackResult; import com.ruoyi.order.util.vo.MapTrackKD100Vo; import com.ruoyi.order.vo.*; import com.ruoyi.other.api.domain.BaseSetting; @@ -79,7 +79,36 @@ return R.ok(confirmOrderVo); } @ResponseBody @PostMapping("/orderPayment") @ApiOperation(value = "订单支付", tags = {"商城-订单支付-小程序"}) public R orderPayment(@RequestBody OrderPayment orderPayment){ return orderService.orderPayment(orderPayment); } /** * 订单支付回调通知 */ @ResponseBody @GetMapping("/orderPaymentCallback") public void orderPaymentCallback(UniPayCallbackResult uniPayCallbackResult, HttpServletResponse response){ String jsonString = JSONObject.toJSONString(uniPayCallbackResult); System.out.println("1111111111111111111111"); System.out.println(jsonString); R callback = orderService.orderPaymentCallback(uniPayCallbackResult); if(callback.getCode() == 200){ response.setStatus(200); PrintWriter out = null; try { out = response.getWriter(); } catch (IOException e) { throw new RuntimeException(e); } out.println("success"); out.flush(); out.close(); } } /** * 我的订单列表 @@ -270,7 +299,7 @@ /** * 订单统计 */ @GetMapping("/getOrderStatistics") /* @GetMapping("/getOrderStatistics") @ApiOperation(value = "订单统计", tags = {"管理后台-首页统计"}) public R<OrderStatistics> getOrderStatistics(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) { @@ -348,7 +377,7 @@ return R.ok(orderStatistics); } */ /** * 订单取消支付回退 * @@ -434,12 +463,12 @@ } /** /* *//** * 获取订单快递明细 * * @param id * @return */ *//* @GetMapping("/getOrderExpress/{id}") @ApiOperation(value = "获取订单快递明细", tags = {"小程序-订单管理"}) public R<MapTrackKD100Vo> getOrderExpress(@PathVariable("id") Long id) { @@ -451,7 +480,7 @@ } return R.ok(); } */ /** * 根据id获取订单详情 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderGoodController.java
@@ -51,7 +51,7 @@ /** * 获取指定用户未分销的订单 */ @PostMapping("/getUnDistributedOrder") /* @PostMapping("/getUnDistributedOrder") public R<List<OrderGood>> getUnDistributedOrder(@RequestBody List<Long> appUserIds) { List<Order> list = orderService.list(new LambdaQueryWrapper<Order>() .in(Order::getAppUserId, appUserIds) @@ -65,6 +65,6 @@ List<OrderGood> orderGoods = orderGoodService.list(new LambdaQueryWrapper<OrderGood>() .in(OrderGood::getOrderId, orderIds)); return R.ok(orderGoods); } }*/ } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
@@ -5,6 +5,7 @@ import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.order.model.Order; import com.ruoyi.order.util.payment.model.RefundCallbackResult; import com.ruoyi.order.util.payment.model.UniPayCallbackResult; import com.ruoyi.order.vo.*; import org.springframework.web.multipart.MultipartFile; @@ -104,5 +105,22 @@ Integer getShopSaleNumByShopIds(List<Integer> shopIds, Integer type); /** * 确认订单 */ ConfirmOrderVo confirmOrder(Integer goodId,Integer type); /** * 订单支付 */ R orderPayment(OrderPayment orderPayment); /** * 订单支付回调通知 */ R orderPaymentCallback(UniPayCallbackResult uniPayCallbackResult); /** * 定时任务关闭订单 */ void closeOrder(); } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -1,40 +1,35 @@ package com.ruoyi.order.service.impl; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.api.feignClient.*; import com.ruoyi.account.api.model.*; import com.ruoyi.account.api.vo.CouponInfoVo; import com.ruoyi.account.api.vo.PaymentUserCoupon; import com.ruoyi.account.api.vo.PaymentUserCouponVo; import com.ruoyi.common.core.constant.ExpressCompanyMap; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.HttpUtils; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.bean.BeanUtils; import com.ruoyi.common.core.utils.uuid.QRCodeGenerator; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.order.enums.OrderStatus; import com.ruoyi.order.event.ConfirmDeliveryEvent; import com.ruoyi.order.mapper.OrderGoodMapper; import com.ruoyi.order.mapper.OrderMapper; import com.ruoyi.order.model.Order; import com.ruoyi.order.model.OrderGood; import com.ruoyi.order.service.OrderGoodService; import com.ruoyi.order.service.OrderService; import com.ruoyi.order.util.ExpressDeliveryUtil; import com.ruoyi.order.util.payment.PaymentUtil; import com.ruoyi.order.util.payment.model.RefundCallbackResult; import com.ruoyi.order.util.payment.model.RefundResult; import com.ruoyi.order.util.vo.MapTrackKD100Vo; import com.ruoyi.order.util.vo.QueryKD100ListVo; import com.ruoyi.order.util.payment.model.*; import com.ruoyi.order.vo.*; import com.ruoyi.other.api.domain.*; import com.ruoyi.other.api.feignClient.*; @@ -44,34 +39,27 @@ import com.ruoyi.system.api.feignClient.SysConfigClient; import com.ruoyi.system.api.feignClient.SysUserClient; import com.ruoyi.system.api.model.LoginUser; import lombok.SneakyThrows; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.jetbrains.annotations.Nullable; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; /** @@ -82,6 +70,7 @@ * @author luodangjia * @since 2024-11-21 */ @Slf4j @Service public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService { @Resource @@ -112,7 +101,13 @@ private OrderGoodService orderGoodService; @Resource private UserPointClient userPointClient; @Resource private RedisTemplate redisTemplate; @Resource private ShopBalanceStatment shopBalanceStatment; @Resource private SystemConfigClient systemConfigClient; @@ -141,33 +136,17 @@ } // 商品 List<OrderGood> orderGoods = orderGoodMapper.selectList(new LambdaQueryWrapper<OrderGood>() .eq(OrderGood::getOrderId, orderId)); OrderGood orderGood = orderGoodMapper.selectOne(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, orderId)); String goodJson = orderGood.getGoodJson(); Goods goods = JSONObject.parseObject(goodJson, Goods.class); List<OrderGoodsVO> goodsList = new ArrayList<>(); for (OrderGood orderGood : orderGoods) { String goodJson = orderGood.getGoodJson(); Goods goods = JSONObject.parseObject(goodJson, Goods.class); OrderGoodsVO orderGoodsVO = new OrderGoodsVO(); orderGoodsVO.setGoodsId(orderGood.getGoodsId()); orderGoodsVO.setNum(orderGood.getNum()); orderGoodsVO.setGoodsName(goods.getName()); orderGoodsVO.setType(goods.getType()); orderGoodsVO.setGoodsPic(goods.getHomePagePicture()); orderGoodsVO.setSellingPrice(orderGood.getSellingPrice()); orderGoodsVO.setIntegral(orderGood.getIntegral()); orderGoodsVO.setOriginalPrice(goods.getOriginalPrice()); goodsList.add(orderGoodsVO); } // 优惠券 String couponJson = order.getCouponJson(); JSONObject jsonObject = new JSONObject(); if (StringUtils.isNotEmpty(couponJson)) { jsonObject = JSONObject.parseObject(couponJson); } OrderGoodsVO orderGoodsVO = new OrderGoodsVO(); BeanUtils.copyProperties(orderGood, orderGoodsVO); orderGoodsVO.setGoodsName(goods.getName()); orderGoodsVO.setGoodsPic(goods.getHomePagePicture()); OrderDetailVO orderDetailVO = new OrderDetailVO(); orderDetailVO.setDistributionMode(order.getDistributionMode()); orderDetailVO.setOrderGoodsVO(orderGoodsVO); Shop shop = shopR.getData(); orderDetailVO.setId(order.getId()); orderDetailVO.setOrderStatus(order.getOrderStatus()); @@ -175,23 +154,12 @@ orderDetailVO.setOrderNumber(order.getOrderNumber()); orderDetailVO.setCreateTime(order.getCreateTime()); orderDetailVO.setTotalAmount(order.getTotalAmount()); orderDetailVO.setCouponName(jsonObject.getString("couponName")); orderDetailVO.setCouponAmount(order.getDiscountTotalAmount()); orderDetailVO.setExpressAmount(order.getExpressAmount()); orderDetailVO.setPointAmount(order.getGetPoint()); orderDetailVO.setPaymentAmount(order.getPaymentAmount()); orderDetailVO.setGoodsList(goodsList); orderDetailVO.setShopName(shop.getName()); orderDetailVO.setShopAddress(shop.getAddress()); orderDetailVO.setLongitude(shop.getLongitude()); orderDetailVO.setLatitude(shop.getLatitude()); orderDetailVO.setShopId(shop.getId()); if (StringUtils.isNotEmpty(order.getExpressResult())) { MapTrackKD100Vo mapTrackKD100Vo = JSON.parseObject(order.getExpressResult(), MapTrackKD100Vo.class); List<QueryKD100ListVo> data = mapTrackKD100Vo.getData(); orderDetailVO.setExpress(null != data && data.size() > 0 ? data.get(0).getContext() : ""); } // 生成核销码BASE64 try { String base64 = QRCodeGenerator.generateQRCodeBase64(String.valueOf(order.getId()), 124, 124); @@ -240,7 +208,7 @@ order.setEndTime(LocalDateTime.now()); order.setCancellerAppUserId(loginUserApplet.getUserid()); if (StringUtils.isNotEmpty(technicianId) && !"null".equals(technicianId)) { order.setTechnicianId(Integer.valueOf(technicianId)); // order.setTechnicianId(Integer.valueOf(technicianId)); } orderMapper.updateById(order); } @@ -371,9 +339,14 @@ return R.fail("订单取消失败"); } order.setOrderStatus(5); //todo 商品销售数量 R r = refundPayMoney(order); if (200 == r.getCode()) { this.updateById(order); } R r2 = userPointClient.deleteUserPointCopy(orderId, Arrays.asList(8));//门店业绩 if (200 != r2.getCode()) { // 项目没有分布式事务,此处报错可能会导致数据不一致 throw new RuntimeException("订单取消失败"); } return r; } @@ -412,11 +385,11 @@ */ public R refundPayMoney(Order order) { //开始退款 Integer payMethod = order.getPayMethod(); BigDecimal expressAmount = order.getExpressAmount() == null ? BigDecimal.ZERO : order.getExpressAmount(); BigDecimal paymentAmount = order.getPaymentAmount().add(expressAmount); BigDecimal paymentAmount = order.getPaymentAmount(); AppUser appUser = appUserClient.getAppUserById(order.getAppUserId()); if (1 == payMethod) { if (BigDecimal.ZERO.compareTo(order.getPaymentAmount()) < 0) {//支付的金额是否大于0 //微信退款 RefundResult refund = PaymentUtil.refund(order.getOrderNumber(), "R" + order.getOrderNumber(), paymentAmount.doubleValue(), "/order/order/refundPayMoneyCallback"); if ("100".equals(refund.getRa_Status())) { @@ -426,38 +399,8 @@ return R.fail(refund.getRc_CodeMsg()); } } if (2 == payMethod) { BigDecimal balance = appUser.getBalance(); appUser.setBalance(balance.add(paymentAmount).setScale(2, RoundingMode.HALF_EVEN)); appUser.setShopAmount(appUser.getShopAmount().subtract(paymentAmount).setScale(2, RoundingMode.HALF_EVEN)); //查询最后一次的消费订单 Order order1 = this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getAppUserId, order.getAppUserId()).eq(Order::getPayStatus, 2) .eq(Order::getDelFlag, 0).in(Order::getOrderStatus, Arrays.asList(1, 2, 3, 4, 8)).ne(Order::getId, order.getId()).last(" order by create_time desc limit 0, 1")); if (null != order1) { appUser.setLastShopTime(order1.getCreateTime()); } else { appUser.setLastShopTime(null); } } if (3 == payMethod) { //开始运费退款,积分支付,运费是单独进行支付的,所以需要单独退款 if (null != order.getExpressAmount() && BigDecimal.ZERO.compareTo(order.getExpressAmount()) < 0) { if (1 == order.getExpressPayMethod()) { //微信退款 RefundResult refund = PaymentUtil.refund(order.getOrderNumber(), "R" + order.getOrderNumber(), expressAmount.doubleValue(), "/order/order/refundExpressPayMoneyCallback"); if ("100".equals(refund.getRa_Status())) { order.setRefundStatus(1); return R.ok(); } else { return R.fail(refund.getRc_CodeMsg()); } } if (2 == order.getExpressPayMethod()) { BigDecimal balance = appUser.getBalance(); appUser.setBalance(balance.add(expressAmount).setScale(2, RoundingMode.HALF_EVEN)); } } if (0 != order.getPoint()) {//使用的积分是否为0 Integer lavePoint = appUser.getLavePoint(); //积分退款 appUser.setLavePoint(appUser.getLavePoint() + order.getPoint()); @@ -465,13 +408,37 @@ UserPoint userPoint1 = new UserPoint(); userPoint1.setType(11); userPoint1.setObjectId(order.getId()); List<UserPoint> data = userPointClient.getUserPointList(userPoint1).getData();//用户积分流水 Integer transferablePoint = order.getPoint(); if (data.size() > 0) { UserPoint userPoint = data.get(0); transferablePoint = Integer.valueOf(userPoint.getExtention()); } appUser.setTransferablePoint(appUser.getTransferablePoint() + transferablePoint); //构建积分流水明细 if (order.getPoint() > 0) { UserPoint userPoint = new UserPoint(); userPoint.setType(11); userPoint.setHistoricalPoint(lavePoint); userPoint.setVariablePoint(order.getPoint()); userPoint.setBalance(appUser.getLavePoint()); userPoint.setCreateTime(LocalDateTime.now()); userPoint.setAppUserId(order.getAppUserId()); userPoint.setObjectId(order.getId()); userPointClient.saveUserPoint(userPoint); } appUserClient.editAppUserById(appUser); } order.setRefundStatus(2); order.setRefundTime(LocalDateTime.now()); orderMapper.updateById(order); //todo 退款后店铺积分流水以及退款前店铺积分流水 /* shopPointClient.deleteShopPointCopy(order.getId(), Arrays.asList(1,2,3)); shopBalanceStatementClient.deleteShopBalanceStatementCopy(order.getId(), Arrays.asList(1,2,3)); appUserGiveawayTemporaryClient.delAppUserGiveawayTemporary(order.getId()); shopGiveawayTemporaryClient.delShopGiveawayTemporary(order.getId());*/ return R.ok(); } @@ -547,22 +514,16 @@ orderInfo.setUserName(appUser.getName()); orderInfo.setPhone(appUser.getPhone()); } orderInfo.setOrderType(order.getOrderType() == 1 ? "服务" : (StringUtils.isNotEmpty(order.getAddressJson()) ? "单品-快递配送" : "单品-上门自提")); Shop shop = shopClient.getShopById(order.getShopId()).getData(); if (null != shop) { orderInfo.setShopName(shop.getName()); } orderInfo.setPaymentMethod(order.getPayMethod()); orderInfo.setTotalAmount(order.getTotalAmount()); orderInfo.setDiscountAmount(order.getDiscountTotalAmount()); orderInfo.setExpressAmount(order.getExpressAmount()); orderInfo.setPaymentAmount(order.getPaymentAmount()); orderInfo.setGetPoint(order.getGetPoint()); if (StringUtils.isNotEmpty(order.getExpressJson()) && !order.getExpressJson().equals("NULL")){ JSONObject jsonObject = JSON.parseObject(order.getExpressJson()); orderInfo.setExpressCompany(jsonObject.getString("com")); orderInfo.setExpressNumber(jsonObject.getString("num")); } List<OrderGood> orderGoods = orderGoodMapper.selectList(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, orderId).eq(OrderGood::getDelFlag, 0)); int sum = orderGoods.stream().mapToInt(OrderGood::getNum).sum(); @@ -657,8 +618,6 @@ confirmOrderVo.setShopName(shop.getShopName()); confirmOrderVo.setPurchaseLimitNum(good.getPurchaseLimit()); confirmOrderVo.setOriginalPrice(good.getOriginalPrice()); //todo 实时计算用户可用积分 confirmOrderVo.setResidualPoint(appUser.getAvailablePoint()); //插入价格 @@ -666,7 +625,7 @@ confirmOrderVo.setPoint(good.getIntegral()); //计算活动价格信息 Price price = getPrice(goodId, 1); Price price = getPrice(goodId); if (null != price) { confirmOrderVo.setCash(price.getCash()); confirmOrderVo.setOrderPoint(price.getPoint()); @@ -687,7 +646,7 @@ confirmOrderVo.setIsPurchaseLimit(false); confirmOrderVo.setPurchaseLimitNum(-1); }else{ //todo 查当前用户的订单 // 查当前用户的订单 List<Order> orders = this.list(new LambdaQueryWrapper<Order>().eq(Order::getAppUserId, appUser.getId()).eq(Order::getDelFlag, 0).in(Order::getOrderStatus, Arrays.asList(4, 8))); List<Long> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList()); int sum = 0; @@ -703,26 +662,290 @@ return confirmOrderVo; } /** * 订单支付 * */ @Override public R orderPayment(OrderPayment orderPayment) { Long userid = tokenService.getLoginUserApplet().getUserid(); AppUser appUser = appUserClient.getAppUserById(userid); int type=1;//商品类型 1=普通商品,2=秒杀商品 //商品信息 Goods goods = goodsClient.getGoodsById(orderPayment.getGoodId()).getData(); if (null == goods || 1==goods.getDelFlag()){ return R.fail( "商品不存在"); } if(goods.getStatus() == 1){ return R.fail(goods.getName() + "商品已被下架"); } //是否在秒杀活动中 GetSeckillActivityInfo info = new GetSeckillActivityInfo(); info.setGoodsId(orderPayment.getGoodId()); GoodsSeckill goodsSeckill = seckillActivityInfoClient.getSeckillActivityInfo(info).getData(); if (null != goodsSeckill){ //秒杀商品 type=2; //判断当前数量是否已经超出限购数量(需要计算已经购买的数量) Integer goodsSaleNum = orderMapper.getGoodsSaleNum(orderPayment.getGoodId(), 2, userid);//已购买数量 SeckillActivityInfo activityInfo = seckillActivityInfoClient.getSeckillActivityInfoById(goodsSeckill.getSeckillActivityInfoId()).getData(); if(null != activityInfo.getMaxNum() && -1 != activityInfo.getMaxNum() && (goodsSaleNum + 1) > activityInfo.getMaxNum()){ return R.fail(goods.getName() + "已超出秒杀活动购买上限"); } //价格 goods.setSellingPrice(goodsSeckill.getSellingPrice());//秒杀活动价格 goods.setIntegral(goodsSeckill.getIntegral());//秒杀活动积分价格 }else { //普通商品 //判断当前数量是否已经超出限购数量(需要计算已经购买的数量) Integer goodsSaleNum = orderMapper.getGoodsSaleNum(orderPayment.getGoodId(), 1, userid);//已购买数量 //普通商品 if(null != goods.getPurchaseLimit() && -1 != goods.getPurchaseLimit() && (goodsSaleNum + 1) > goods.getPurchaseLimit()){ return R.fail(goods.getName() + "已超出购买上限"); } } //判断支付方式是否正确 if(1 != orderPayment.getPaymentType() && 3 != orderPayment.getPaymentType()){ return R.fail("支付方式不正确"); } //现金支付的订单总金额 BigDecimal orderMoney = BigDecimal.ZERO; //积分支付的订单积分 Integer orderPoint = 0; //现金的实际支付金额 BigDecimal paymentMoney = BigDecimal.ZERO; //积分抵扣金额 BigDecimal pointDeductionAmount = BigDecimal.ZERO; if(3 != orderPayment.getPaymentType()){ //现金支付 orderMoney = goods.getSellingPrice(); paymentMoney=orderMoney.setScale(2, RoundingMode.HALF_EVEN);; //是否使用积分抵扣 if (orderPayment.getIsPointDeduction() == 1) { //积分抵扣金额 Integer availablePoint = appUser.getAvailablePoint();//用户可用积分 BigDecimal maxPointDeductionAmount = getCashByPoint(availablePoint);//最大可抵扣金额 pointDeductionAmount=maxPointDeductionAmount.min(orderMoney);//实际抵扣金额 // 计算实际支付金额 paymentMoney = orderMoney.subtract(pointDeductionAmount).setScale(2, RoundingMode.HALF_EVEN); //计算消耗积分 orderPoint=getPoint(pointDeductionAmount); } }else{ //积分支付 orderPoint=goods.getIntegral(); Integer availablePoint = appUser.getAvailablePoint();//用户可用积分 if(availablePoint.compareTo(orderPoint) < 0){ return R.fail("账户可用积分不足"); } } //构建订单 Order order = new Order(); order.setAppUserId(appUser.getId()); order.setNum(1); order.setGoodPics(goods.getHomePagePicture()); order.setGoodName(goods.getName()); order.setOrderStatus( 3 );//待使用 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); order.setOrderNumber("QJS" + getNumber(3) + sdf.format(new Date())); order.setTotalAmount(orderMoney.setScale(2, RoundingMode.HALF_EVEN));//订单总金额 order.setPointDeductionAmount(pointDeductionAmount.setScale(2, RoundingMode.HALF_EVEN)); order.setPaymentAmount(paymentMoney);//实际支付价格 order.setPoint(orderPoint);//使用积分 order.setPayMethod(orderPayment.getPaymentType());//支付方式 order.setPayStatus(1); order.setShopId(orderPayment.getShopId()); order.setDelFlag(0); order.setCreateTime(LocalDateTime.now()); orderMapper.insert(order); //构建订单明细数据 OrderGood orderGood = new OrderGood(); orderGood.setGoodsId(goods.getId()); orderGood.setOrderId(order.getId()); orderGood.setNum(1); orderGood.setType(type); if (2==type){ orderGood.setSeckillJson(JSON.toJSONString(goodsSeckill)); } orderGood.setGoodJson(JSON.toJSONString(goods)); orderGood.setDelFlag(0); orderGood.setCreateTime(LocalDateTime.now()); orderGood.setCashPayment(orderPayment.getPaymentType()==1 ? 1 : 0); orderGood.setPointPayment(orderPayment.getPaymentType()==3 ? 1 : 0); orderGood.setSellingPrice(goods.getSellingPrice()); orderGood.setIntegral(goods.getIntegral()); orderGoodService.save(orderGood); //开始构建支付信息 if(BigDecimal.ZERO.compareTo(paymentMoney) > 0){ paymentMoney = BigDecimal.ZERO; } //判断积分是否为零,积分支付 if (0 != order.getPoint()){ //积分支付 Integer lavePoint = appUser.getLavePoint(); //扣减订单支付积分 appUser.setLavePoint(appUser.getLavePoint() - orderPoint); appUser.setAvailablePoint(appUser.getAvailablePoint() - orderPoint); //可转赠积分 Integer transferablePoint = appUser.getTransferablePoint(); Integer tra = 0; if(transferablePoint > 0){ tra = transferablePoint - orderPoint; appUser.setTransferablePoint(tra >= 0 ? tra : 0); }else{ appUser.setTransferablePoint(appUser.getTransferablePoint() - orderPoint); } //构建积分流水记录 if(orderPoint > 0){ UserPoint userPoint = new UserPoint(); userPoint.setType(11); userPoint.setHistoricalPoint(lavePoint); userPoint.setVariablePoint(orderPoint); userPoint.setBalance(appUser.getLavePoint()); userPoint.setCreateTime(LocalDateTime.now()); userPoint.setAppUserId(appUser.getId()); userPoint.setObjectId(order.getId()); userPoint.setExtention((tra >= 0 ? orderPoint : transferablePoint) + ""); userPointClient.saveUserPoint(userPoint); } appUser.setLastShopTime(LocalDateTime.now()); appUserClient.editAppUserById(appUser); /* //变更等级 applicationEventPublisher.publishEvent(new PayEvent(JSON.toJSONString(appUser)));*/ } //判断需要支付的金额是否大于0 if ( BigDecimal.ZERO.compareTo(paymentMoney) < 0){ //调起微信支付 String goodsNames = goods.getName(); UniPayResult uniPayResult = PaymentUtil.uniPay(order.getOrderNumber(), paymentMoney.doubleValue(), "购买单品商品", goodsNames, "", "/order/order/orderPaymentCallback", appUser.getWxOpenid(), null); if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){ return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg()); } String rc_result = uniPayResult.getRc_Result(); JSONObject jsonObject = JSON.parseObject(rc_result); jsonObject.put("orderId", order.getId().toString()); //将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。 long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC); redisTemplate.opsForZSet().add("OrderPayment", order.getOrderNumber(), second); return R.ok(jsonObject.toJSONString()); } //不需要微信支付,直接修改订支付状态 order.setPayStatus(2); orderMapper.updateById(order); //商品销量增加 goodsClient.editGoodsNum(orderGood.getGoodsId(), 1); //todo 门店增加冻结资金 return R.ok(order.getId().toString()); } /** * 订单支付回调通知 */ @Override public R orderPaymentCallback(UniPayCallbackResult uniPayCallbackResult) { Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, uniPayCallbackResult.getR2_OrderNo())); if(null == order || order.getPayStatus() == 2){ return R.ok(); } AppUser appUser = appUserClient.getAppUserById(order.getAppUserId()); BigDecimal paymentMoney = order.getPaymentAmount(); //构建积分流水记录 appUser.setShopAmount(appUser.getShopAmount().add(paymentMoney).setScale(2, RoundingMode.HALF_EVEN));//消费总金额 appUser.setLastShopTime(LocalDateTime.now()); appUserClient.editAppUserById(appUser); //修改订支付状态 order.setPayStatus(2); //待使用 order.setOrderStatus(3); String r7TrxNo = uniPayCallbackResult.getR9_BankTrxNo(); order.setSerialNumber(r7TrxNo); orderMapper.updateById(order); //商店余额改变,增加冻结余额 Shop shop = shopClient.getShopById(order.getShopId()).getData(); //商品销量增加 OrderGood orderGood = orderGoodService.getOne(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, order.getId())); goodsClient.editGoodsNum(orderGood.getGoodsId(), 1); return R.ok(); } /** * 定时任务关闭订单 */ @Override public void closeOrder() { //订单支付数据 long second = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC); Set<String> orderPayment = redisTemplate.opsForZSet().rangeByScore("OrderPayment", 0, second); if(orderPayment.size() > 0){ List<Order> list = orderMapper.selectList(new LambdaQueryWrapper<Order>().in(Order::getOrderNumber, orderPayment)); for (Order order : list) { if(null == order || order.getPayStatus() != 1){ redisTemplate.opsForZSet().remove("OrderPayment", order.getOrderNumber()); continue; } //开始执行关闭订单操作 CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(order.getOrderNumber()); if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) && Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){ redisTemplate.opsForZSet().add("OrderPayment", order.getOrderNumber(), 0); log.error("关闭订单失败:{}---->{}", order.getOrderNumber(), JSON.toJSONString(closeOrderResult)); } redisTemplate.opsForZSet().remove("OrderPayment", order.getOrderNumber()); } } } public String getNumber(Integer size){ StringBuilder str = new StringBuilder(); for (int i = 0; i < size; i++) { str.append(Double.valueOf(Math.random() * 10).intValue()); } return str.toString(); } /** * 根据商品的价格配置体系获取商品当前的价格 * @param goodsId * @param type 1普通商品,2秒杀商品 * @return */ public Price getPrice( Integer goodsId, Integer type){ //判断是否有在秒杀活动时间中 public Price getPrice( Integer goodsId){ //判断是否有在秒杀活动时间中的商品 Price price = new Price(); GetSeckillActivityInfo getSeckillActivityInfo = new GetSeckillActivityInfo(); getSeckillActivityInfo.setGoodsId(goodsId); GoodsSeckill goodsSeckill = seckillActivityInfoClient.getSeckillActivityInfo(getSeckillActivityInfo).getData(); //没有秒杀活动或者添加的普通商品则使用秒杀活动价格 if(null == goodsSeckill || type == 1){ //没有秒杀活动 if(null == goodsSeckill ){ return null; } //秒杀活动价格 price.setCash(goodsSeckill.getSellingPrice()); //计算对应积分 price.setPoint(getPoint(price.getCash())); //结束时间 price.setEndTimeStamp(goodsSeckill.getEndTime()); return price; } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/TaskUtil.java
New file @@ -0,0 +1,39 @@ package com.ruoyi.order.util; import com.ruoyi.order.service.OrderService; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * @author zhibing.pu * @date 2023/7/11 8:39 */ @Component public class TaskUtil { @Resource private OrderService orderService; @Scheduled(fixedRate = 60000) public void taskMonth() { orderService.closeOrder();//定时任务关闭订单 } // 每天晚上23:59:59执行的定时任务 @Scheduled(cron = "0 0 23 * * ?") public void taskLastDay() { } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/GoodsController.java
@@ -85,7 +85,7 @@ @PutMapping("/manageGoodsUpdate") @ApiOperation(value = "商品修改", tags = {"管理后台-商品管理"}) public R<Void> manageGoodsUpdate(@RequestBody Goods goods){ if(goods.getPurchaseLimit()==null){ /* if(goods.getPurchaseLimit()==null){ goods.setPurchaseLimit(-1); } goodsService.updateManageGoods(goods); @@ -98,7 +98,7 @@ goodsLambdaUpdateWrapper.set(Goods::getDistributionMode,null); goodsLambdaUpdateWrapper.eq(Goods::getId, goods.getId()); goodsService.update(goodsLambdaUpdateWrapper); } }*/ return R.ok(); } @@ -180,14 +180,13 @@ /** * 根据类型(1=服务商品,2=单品商品)获取商品数据 * @param type * 获取商品数据 * @return */ @ResponseBody @PostMapping("/getGoodsByType") public R<List<Goods>> getGoodsByType(@RequestParam("type") Integer type){ List<Goods> list = goodsService.list(new LambdaQueryWrapper<Goods>().eq(Goods::getType, type).eq(Goods::getDelFlag, 0).eq(Goods::getStatus, 2)); public R<List<Goods>> getGoodsByType(){ List<Goods> list = goodsService.list(new LambdaQueryWrapper<Goods>().eq(Goods::getDelFlag, 0).eq(Goods::getStatus, 2)); return R.ok(list); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopBalanceStatementController.java
New file @@ -0,0 +1,425 @@ package com.ruoyi.other.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.poi.ExcelUtil; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.other.api.domain.Shop; import com.ruoyi.other.api.domain.ShopBalanceStatement; import com.ruoyi.other.dto.ShopBalanceDto; import com.ruoyi.other.mapper.ShopBalanceStatementMapper; import com.ruoyi.other.service.ShopBalanceStatementService; import com.ruoyi.other.service.ShopService; import com.ruoyi.other.vo.ShopBalanceStatementDetailPage; import com.ruoyi.other.vo.ShopCommission; import com.ruoyi.other.vo.ShopCommissionDetail; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysUserClient; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.apache.commons.lang3.tuple.Pair; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** * <p> * 前端控制器 * </p> * * @author luodangjia * @since 2024-11-20 */ @RestController @RequestMapping("/shop-balance-statement") @Api(tags = "管理后台-财务统计-门店分佣统计") public class ShopBalanceStatementController { @Resource private ShopBalanceStatementService shopBalanceStatementService; @Resource private TokenService tokenService; @Resource private ShopBalanceStatementMapper shopBalanceStatementMapper; @Resource private ShopService shopService; @Resource private SysUserClient sysUserClient; /* @Resource private ShopBalanceStatementCopyMapper shopBalanceStatementCopyMapper; @Resource private ShopWithdrawService shopWithdrawService; */ /** * 门店分佣统计 */ /*@GetMapping("/commissionStatistics") @ApiOperation("门店分佣统计") public R<ShopCommissionStatisticsVO> shopCommissionStatistics(@ApiParam("页码") @RequestParam Integer pageNum, @ApiParam("每一页数据大小") Integer pageSize, ShopBalanceStatement shopBalanceStatement) { ShopCommissionStatisticsVO shopCommissionStatisticsVO = shopBalanceStatementService.shopCommissionStatistics(Page.of(pageNum, pageSize), shopBalanceStatement); return R.ok(shopCommissionStatisticsVO); }*/ /** * 导出门店分佣统计 */ /*@GetMapping("/export") @ApiOperation("导出门店分佣统计") public void export(HttpServletResponse response, ShopBalanceStatement shopBalanceStatement) { ShopCommissionStatisticsVO shopCommissionStatisticsVO = shopBalanceStatementService.shopCommissionStatistics(Page.of(1, Integer.MAX_VALUE), shopBalanceStatement); IPage<ShopBalanceStatement> statementIPage = shopCommissionStatisticsVO.getStatementIPage(); ExcelUtil<ShopBalanceStatement> util = new ExcelUtil<>(ShopBalanceStatement.class); util.exportExcel(response, statementIPage.getRecords(), "用户积分统计"); }*/ /*@GetMapping("/commissionStatistics/list") @ApiOperation(value = "门店余额明细", notes = "门店余额明细", tags = {"门店后台"}) public R<Page<ShopBalanceStatement>> shopCommissionStatisticslist(@ApiParam("页码") @RequestParam Integer pageNum, @ApiParam("每一页数据大小") Integer pageSize, ShopBalanceStatement shopBalanceStatement) { Long userid = tokenService.getLoginUser().getUserid(); R<SysUser> sysUserR = sysUserClient.getSysUser(userid); SysUser sysUser = sysUserR.getData(); Integer objectId = sysUser.getObjectId(); Page<ShopBalanceStatement> page = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(shopBalanceStatement.getType() != null, ShopBalanceStatement::getType, shopBalanceStatement.getType()) .orderByDesc(ShopBalanceStatement::getCreateTime) .page(Page.of(pageNum, pageSize)); return R.ok(page); }*/ /*@GetMapping("/commissionStatistics/info") @ApiOperation(value = "门店余额明细上方数据", notes = "门店余额明细", tags = {"门店后台"}) public R<ShopBalanceDto> shopCommissionStatisticsinfo(Integer type) { Integer objectId = tokenService.getLoginUser().getSysUser().getObjectId(); ShopBalanceDto dto = new ShopBalanceDto(); Shop byId = shopService.getById(objectId); if (type == null) { List<ShopBalanceStatement> list = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(ShopBalanceStatement::getType, 3).list(); List<ShopBalanceStatement> list1 = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(ShopBalanceStatement::getType, 1).list(); BigDecimal bigDecimal1 = new BigDecimal(0); for (ShopBalanceStatement shopBalanceStatement : list) { bigDecimal1 = bigDecimal1.add(shopBalanceStatement.getVariableAmount()); } for (ShopBalanceStatement shopBalanceStatement : list1) { bigDecimal1 = bigDecimal1.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal1(bigDecimal1); BigDecimal bigDecimal2 = new BigDecimal(0); for (ShopBalanceStatement shopBalanceStatement : list) { bigDecimal2 = bigDecimal2.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal2(bigDecimal2); BigDecimal bigDecimal3 = new BigDecimal(0); for (ShopBalanceStatement shopBalanceStatement : list1) { bigDecimal3 = bigDecimal3.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal3(bigDecimal3); List<ShopBalanceStatement> list2 = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(ShopBalanceStatement::getType, 2).list(); BigDecimal bigDecimal4 = new BigDecimal(0); for (ShopBalanceStatement shopBalanceStatement : list2) { bigDecimal4 = bigDecimal4.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal4(bigDecimal4); dto.setBigDecimal5(byId.getCanWithdrawMoney()); dto.setBigDecimal6(byId.getWithdrawMoney()); return R.ok(dto); } else { switch (type) { case 1: // 关联用户分拥 BigDecimal bigDecimal = new BigDecimal("0"); List<ShopBalanceStatement> list1 = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(ShopBalanceStatement::getType, 1).list(); for (ShopBalanceStatement shopBalanceStatement : list1) { bigDecimal = bigDecimal.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal3(bigDecimal); dto.setBigDecimal1(bigDecimal); break; case 2: // 下级门店分佣 BigDecimal bigDecimal2 = new BigDecimal(0); List<ShopBalanceStatement> list2 = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(ShopBalanceStatement::getType, 2).list(); for (ShopBalanceStatement shopBalanceStatement : list2) { bigDecimal2 = bigDecimal2.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal4(bigDecimal2); dto.setBigDecimal1(bigDecimal2); break; case 3: // 服务费分佣 List<ShopBalanceStatement> list = shopBalanceStatementService.lambdaQuery().eq(ShopBalanceStatement::getShopId, objectId).eq(ShopBalanceStatement::getType, 3).list(); BigDecimal bigDecimal3 = new BigDecimal(0); for (ShopBalanceStatement shopBalanceStatement : list) { bigDecimal3 = bigDecimal3.add(shopBalanceStatement.getVariableAmount()); } dto.setBigDecimal2(bigDecimal3); dto.setBigDecimal1(bigDecimal3); break; case 4: // 余额提现 dto.setBigDecimal6(byId.getWithdrawMoney()); break; } } return R.ok(dto); } */ /* @PostMapping("/getList") public R<List<ShopBalanceStatement>> getList(@RequestBody ShopBalanceStatement shopBalanceStatement) { return R.ok(shopBalanceStatementMapper.selectShopBalanceStatementList(shopBalanceStatement)); }*/ /** * 保存门店余额流水 * * @param shopBalanceStatement */ @PostMapping("/saveShopBalanceStatement") public void saveShopBalanceStatement(@RequestBody ShopBalanceStatement shopBalanceStatement) { shopBalanceStatementService.save(shopBalanceStatement); } /* @PostMapping("/saveShopBalanceStatementCopy") public void saveShopBalanceStatementCopy(@RequestBody ShopBalanceStatementCopy shopBalanceStatementCopy) { shopBalanceStatementCopyMapper.insert(shopBalanceStatementCopy); }*/ /* @DeleteMapping("/deleteShopBalanceStatementCopy") public R<Boolean> deleteShopBalanceStatementCopy(@RequestParam("orderId") Long orderId, @RequestParam("type") List<Integer> type) { shopBalanceStatementCopyMapper.delete(new LambdaQueryWrapper<ShopBalanceStatementCopy>().in(ShopBalanceStatementCopy::getType, type) .eq(ShopBalanceStatementCopy::getObjectId, orderId)); return R.ok(); } */ /* @PostMapping("/getShopBalanceStatementCopy") public R<List<ShopBalanceStatementCopy>> getShopBalanceStatementCopy(@RequestParam("orderId") Long orderId, @RequestParam("type") List<Integer> type) { List<ShopBalanceStatementCopy> shopBalanceStatementCopies = shopBalanceStatementCopyMapper.selectList(new LambdaQueryWrapper<ShopBalanceStatementCopy>().in(ShopBalanceStatementCopy::getType, type) .eq(ShopBalanceStatementCopy::getObjectId, orderId)); return R.ok(shopBalanceStatementCopies); } */ /** * 获取门店流水数据 * * @param types * @param objectId * @return */ @PostMapping("/getShopBalanceStatementList") public R<List<ShopBalanceStatement>> getShopBalanceStatementList(@RequestParam("types") Collection<Integer> types, @RequestParam(value = "objectId", required = false) Long objectId) { List<ShopBalanceStatement> list = shopBalanceStatementService.list(new LambdaQueryWrapper<ShopBalanceStatement>() .eq(objectId != null, ShopBalanceStatement::getObjectId, objectId) .in(types != null && !types.isEmpty(), ShopBalanceStatement::getType, types)); return R.ok(list); } @PostMapping("/getShopBalanceStatementList2") public R<List<ShopBalanceStatement>> getShopBalanceStatementList2(@RequestParam("type") Integer type, @RequestParam(value = "shopId") Integer shopId, @RequestParam(value = "date") LocalDateTime date) { LambdaQueryWrapper<ShopBalanceStatement> queryWrapper = new LambdaQueryWrapper<ShopBalanceStatement>() .eq(ShopBalanceStatement::getType, type) .between(ShopBalanceStatement::getCreateTime, date.with(LocalTime.MIN), date.with(LocalTime.MAX)); if (null != shopId && 0 != shopId) { queryWrapper.eq(ShopBalanceStatement::getShopId, shopId); }else{ List<Integer> shipIds = shopService.list(new LambdaQueryWrapper<Shop>().eq(Shop::getDelFlag, 0)).stream().map(Shop::getId).collect(Collectors.toList()); if(shipIds.size() > 0){ queryWrapper.in(ShopBalanceStatement::getShopId, shipIds); }else{ queryWrapper.eq(ShopBalanceStatement::getShopId, -1); } } List<ShopBalanceStatement> list = shopBalanceStatementService.list(queryWrapper); return R.ok(list); } /** * 获取门店佣金 * * @param shopId * @return */ /* @GetMapping("getShopCommission") @ApiOperation(value = "获取门店佣金", notes = "获取门店佣金", tags = {"小程序-个人中心-门店管理-门店钱包"}) @Transactional public R<ShopCommission> getShopCommission(@RequestParam("shopId") Integer shopId) { // 合并查询逻辑 List<ShopBalanceStatementCopy> copies = shopBalanceStatementCopyMapper.selectList( new LambdaQueryWrapper<ShopBalanceStatementCopy>() .eq(ShopBalanceStatementCopy::getShopId, shopId)); List<ShopBalanceStatement> statements = shopBalanceStatementService.list( new LambdaQueryWrapper<ShopBalanceStatement>() .eq(ShopBalanceStatement::getShopId, shopId)); // 合并计算 Map<Integer, BigDecimal> result = Stream.concat( copies.stream().map(e -> Pair.of(e.getType(), e.getVariableAmount())), statements.stream().map(e -> Pair.of(e.getType(), e.getVariableAmount())) ).collect(Collectors.groupingBy( Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)) )); // 待审核佣金 BigDecimal waitingAudit = shopWithdrawService.list(new LambdaQueryWrapper<ShopWithdraw>() .eq(ShopWithdraw::getShopId, shopId) .eq(ShopWithdraw::getAuditStatus, 0)) .stream() .map(ShopWithdraw::getMoney) .reduce(BigDecimal.ZERO, BigDecimal::add); // 店铺信息校验 Shop shop = shopService.getById(shopId); if (shop == null) { throw new ServiceException("店铺不存在"); } // 构建结果 List<ShopWithdraw> list = shopWithdrawService.lambdaQuery().eq(ShopWithdraw::getShopId, shopId) .eq(ShopWithdraw::getAuditStatus, 0).list(); BigDecimal withdrawAuditMoney = list.stream().map(ShopWithdraw::getMoney).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); ShopCommission commission = new ShopCommission(); commission.setCanWithdrawCommission(shop.getCanWithdrawMoney()); commission.setWithdrawnCommission(shop.getWithdrawMoney().subtract(withdrawAuditMoney)); commission.setCommissionAmount( result.getOrDefault(1, BigDecimal.ZERO) .add(result.getOrDefault(2, BigDecimal.ZERO) .add(result.getOrDefault(3, BigDecimal.ZERO)) )); commission.setWaitingAuditCommission(waitingAudit); commission.setTotalAmount(commission.getCommissionAmount()); return R.ok(commission); } */ /** * 获取门店佣金明细 */ /* @GetMapping("/getshopCommissionStatisticsDetail") @ApiOperation(value = "门店返佣明细", notes = "门店返佣明细", tags = {"小程序-个人中心-门店管理-门店钱包"}) public R<ShopBalanceStatementDetailPage> shopCommissionStatisticsDetail(@ApiParam("店铺id") Integer shopId, @ApiParam("类型") Integer type, @ApiParam("开始时间") String createTime, @ApiParam("页码") Integer pageNum, @ApiParam("每一页数据大小") Integer pageSize) { LocalDateTime startDate = null; LocalDateTime endDate = null; if (StringUtils.isNotEmpty(createTime)){ startDate = LocalDateTime.parse(createTime + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); endDate = LocalDateTime.parse(createTime + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } List<ShopBalanceStatementCopy> copies = shopBalanceStatementCopyMapper.selectList( new LambdaQueryWrapper<ShopBalanceStatementCopy>() .eq(ShopBalanceStatementCopy::getShopId, shopId) .eq(type != null, ShopBalanceStatementCopy::getType, type) .between(startDate != null && endDate != null, ShopBalanceStatementCopy::getCreateTime, startDate, endDate)); List<ShopBalanceStatement> statements = shopBalanceStatementService.list( new LambdaQueryWrapper<ShopBalanceStatement>() .eq(ShopBalanceStatement::getShopId, shopId) .eq(type != null, ShopBalanceStatement::getType, type) .between(startDate != null && endDate != null, ShopBalanceStatement::getCreateTime, startDate, endDate)); Map<Integer, String> itemMap = new HashMap<>(); itemMap.put(1, "服务商分佣"); itemMap.put(2, "高级服务商分佣"); itemMap.put(3, "核销门店服务费"); itemMap.put(4, "提现"); List<ShopCommissionDetail> list = new ArrayList<>(); for (ShopBalanceStatementCopy copy : copies) { ShopCommissionDetail detail = new ShopCommissionDetail(); detail.setItem(itemMap.get(copy.getType())); detail.setTime(copy.getCreateTime()); detail.setAmount(copy.getVariableAmount()); BigDecimal beforeAmount = copy.getHistoricalBalance(); BigDecimal afterAmount = copy.getBalance(); if (beforeAmount.compareTo(afterAmount) > 0) { detail.setType(2); } else { detail.setType(1); } list.add(detail); } for (ShopBalanceStatement statement : statements) { ShopCommissionDetail detail = new ShopCommissionDetail(); detail.setItem(itemMap.get(statement.getType())); detail.setTime(statement.getCreateTime()); detail.setAmount(statement.getVariableAmount()); BigDecimal beforeAmount = statement.getHistoricalBalance(); BigDecimal afterAmount = statement.getBalance(); if (beforeAmount.compareTo(afterAmount) > 0) { detail.setType(2); } else { detail.setType(1); } list.add(detail); } // 按时间排序加手动分页 Integer total = list.size(); list.sort(Comparator.comparing(ShopCommissionDetail::getTime).reversed()); if (pageNum != null && pageSize != null) { int fromIndex = (pageNum - 1) * pageSize; int toIndex = Math.min(fromIndex + pageSize, list.size()); list = list.subList(fromIndex, toIndex); } ShopBalanceStatementDetailPage page = new ShopBalanceStatementDetailPage(); page.setRecords(list); page.setTotal(total); page.setPageSize(pageSize); page.setPageNum(pageNum); return R.ok(page); }*/ } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java
@@ -253,7 +253,7 @@ @DeleteMapping("/deleteShop") @ApiOperation(value = "删除门店", tags = {"管理后台-门店管理"}) public R<Void> deleteShop(@ApiParam("门店id") @RequestParam("id") Integer id){ List<Goods> list1 = goodsService.list(new LambdaQueryWrapper<Goods>().eq(Goods::getDelFlag, 0).eq(Goods::getAppointStore, 1).eq(Goods::getStatus, 2)); /*List<Goods> list1 = goodsService.list(new LambdaQueryWrapper<Goods>().eq(Goods::getDelFlag, 0).eq(Goods::getAppointStore, 1).eq(Goods::getStatus, 2)); if(list1.size() > 0){ Set<Integer> collect1 = list1.stream().map(Goods::getId).collect(Collectors.toSet()); long count = goodsShopService.count(new LambdaQueryWrapper<GoodsShop>().eq(GoodsShop::getShopId, id).in(GoodsShop::getGoodsId, collect1)); @@ -280,7 +280,7 @@ if(data.size() > 0){ //删除门店后台账号和关系数据 sysUserClient.delShopUser(shop.getId(), 2); } }*/ return R.ok(); } @@ -655,7 +655,7 @@ @GetMapping("/getVerifiableShop") @ApiOperation(value = "获取可核销门店列表", tags = {"购物车-小程序"}) public R<List<VerifiableShopVo>> getVerifiableShop(String longitude, String latitude, Integer goodsId){ String city = TencentMapUtil.inverseGeographicalAnalysis(longitude, latitude, false); /* String city = TencentMapUtil.inverseGeographicalAnalysis(longitude, latitude, false); if(null == city){ city = "510100"; } @@ -689,7 +689,8 @@ return o1.getDistance().compareTo(o2.getDistance()); } }); return R.ok(verifiableShopVoList); return R.ok(verifiableShopVoList);*/ return null; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/ShopBalanceStatementMapper.java
New file @@ -0,0 +1,25 @@ package com.ruoyi.other.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.other.api.domain.ShopBalanceStatement; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> * Mapper 接口 * </p> * * @author luodangjia * @since 2024-11-20 */ public interface ShopBalanceStatementMapper extends BaseMapper<ShopBalanceStatement> { IPage<ShopBalanceStatement> queryShopBalanceStatementPage(@Param("page") IPage<ShopBalanceStatement> page, @Param("bs") ShopBalanceStatement shopBalanceStatement); List<ShopBalanceStatement> selectShopBalanceStatementList(@Param("bs") ShopBalanceStatement shopBalanceStatement); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopBalanceStatementService.java
New file @@ -0,0 +1,18 @@ package com.ruoyi.other.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.other.api.domain.ShopBalanceStatement; import com.ruoyi.other.vo.ShopCommissionStatisticsVO; /** * <p> * 服务类 * </p> * * @author luodangjia * @since 2024-11-20 */ public interface ShopBalanceStatementService extends IService<ShopBalanceStatement> { ShopCommissionStatisticsVO shopCommissionStatistics(IPage<ShopBalanceStatement> page, ShopBalanceStatement shopBalanceStatement); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/GoodsServiceImpl.java
@@ -258,7 +258,7 @@ @Override @Transactional(rollbackFor = Exception.class) public void addGoods(Goods goods) { goods.setSaleNum(0); /* goods.setSaleNum(0); goods.setStatus(GoodsStatus.DOWN.getCode()); goodsMapper.insert(goods); @@ -270,18 +270,18 @@ throw new NullPointerException("请选择指定门店"); } saveGoodsShopList(goodsShopList, goods.getId()); } }*/ } @Override public void updateManageGoods(Goods goods) { this.updateById(goods); /* this.updateById(goods); //修改个别字段 this.update(new LambdaUpdateWrapper<Goods>().eq(Goods::getId, goods.getId()).set(Goods::getSellingPrice, goods.getSellingPrice()) .set(Goods::getIntegral, goods.getIntegral())); // 指定门店 List<GoodsShop> goodsShopList = goods.getGoodsShopList(); saveGoodsShopList(goodsShopList, goods.getId()); saveGoodsShopList(goodsShopList, goods.getId());*/ } @@ -322,7 +322,7 @@ goodsShop.setAddress(shop.getAddress()); } } goods.setGoodsShopList(goodsShops); // goods.setGoodsShopList(goodsShops); return goods; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/SeckillActivityInfoServiceImpl.java
@@ -136,7 +136,7 @@ @Override public SeckillActivityDetailVO detail(Integer seckillActivityId, String latitude, String longitude) { Integer vipId = 0; /* Integer vipId = 0; String token = SecurityUtils.getToken(ServletUtils.getRequest()); if(StringUtils.isNotEmpty(token)){ Long userid = tokenService.getLoginUserApplet().getUserid(); @@ -184,7 +184,8 @@ seckillActivityDetailVO.setShopList(shops); Integer integer = orderClient.getGoodsSaleNum(goods.getId(), 2).getData(); seckillActivityDetailVO.setSaleNum(integer); return seckillActivityDetailVO; return seckillActivityDetailVO;*/ return null; } @Override ruoyi-service/ruoyi-other/src/main/resources/mapper/other/ShopBalanceStatementMapper.xml
New file @@ -0,0 +1,40 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.other.mapper.ShopBalanceStatementMapper"> <sql id="shopBalanceStatementList"> SELECT tsbs.*, ts.`name` shopName, ts.shop_manager shopManagerName, ts.phone FROM t_shop_balance_statement tsbs INNER JOIN t_shop ts ON ts.id = tsbs.shop_id <where> tsbs.type != 4 and ts.del_flag = 0 <if test="bs.shopName != null and bs.shopName != ''"> AND ts.`name` like concat('%', #{bs.shopName}, '%') </if> <if test="bs.shopManagerName != null and bs.shopManagerName != ''"> AND ts.shop_manager like concat('%', #{bs.shopManagerName}, '%') </if> <if test="bs.phone != null and bs.phone != ''"> AND ts.phone like concat('%', #{bs.phone}, '%') </if> <if test="bs.type != null"> AND tsbs.type = #{bs.type} </if> <if test="bs.startTime != null and bs.endTime != null"> AND tsbs.create_time BETWEEN #{bs.startTime} AND #{bs.endTime} </if> </where> </sql> <select id="queryShopBalanceStatementPage" resultType="com.ruoyi.other.api.domain.ShopBalanceStatement"> <include refid="shopBalanceStatementList"/> </select> <select id="selectShopBalanceStatementList" resultType="com.ruoyi.other.api.domain.ShopBalanceStatement"> <include refid="shopBalanceStatementList"/> </select> </mapper>