ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/ApplyForAdmission.java
@@ -70,6 +70,31 @@ @TableId("address") private String address; @ApiModelProperty(value = "省") @TableField("province") private String province; @ApiModelProperty(value = "省编号") @TableField("province_code") private String provinceCode; @ApiModelProperty(value = "市") @TableField("city") private String city; @ApiModelProperty(value = "市编号") @TableField("city_code") private String cityCode; @ApiModelProperty(value = "区") @TableField("district") private String district; @ApiModelProperty(value = "区编号") @TableField("district_code") private String districtCode; @ApiModelProperty(value = "状态(0-待审核,1-审核通过,2-审核不通过)") @TableField("status") private Integer status; ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/model/Order.java
@@ -67,6 +67,7 @@ @TableField("num") private Integer num; //todo 商品封面 @ApiModelProperty(value = "商品封面(多张逗号隔开,最多三张))") @TableField("good_pics") private String goodPics; ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/OrderDetailVO.java
@@ -52,6 +52,8 @@ @ApiModelProperty(value = "门店id") private Integer shopId; @ApiModelProperty(value = "评价id") private Long evaluateId; @ApiModelProperty("核销码BASE64") private String writeOffCode; ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/OrderGoodsVO.java
@@ -15,8 +15,6 @@ @ApiModelProperty(value = "商品名称") private String goodsName; @ApiModelProperty(value = "类型(1=服务商品,2=单品商品)") private Integer type; @ApiModelProperty(value = "数量") private Integer num; ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/vo/Price.java
@@ -29,59 +29,8 @@ private Long endTimeStamp; /** * 现金支付 * 活动限购数量 */ private Boolean cashPayment; /** * 积分支付 */ private Boolean pointPayment; /** * 可获得消费积分 */ private Integer earnSpendingPoints; /** * 上级获得分佣金额 */ private BigDecimal superiorSubcommission; /** * 上级获得返佣积分 */ private Integer superiorRebatePoints; /** * 获取返佣积分上级类型(1=直推上级,2=直帮上级) */ private String superiorType; /** * 获取分佣金额上级类型(1=直推上级,2=直帮上级) */ private String superiorPriceType; /** * 核销门店可获得服务费 */ private BigDecimal servuceShopCharges; /** * 核销门店可获得服务积分 */ private Integer servuceShopPoints; /** * 技师可获得服务积分 */ private Integer technicianPoints; /** * 绑定门店可获得分佣金额 */ private BigDecimal boundShopCharges; /** * 绑定门店可获得返佣积分 */ private Integer boundShopPoints; /** * 绑定门店上级门店可获得分佣金额 */ private BigDecimal boundShopSuperiorsCharges; /** * 绑定门店上级门店可获得返佣积分 */ private Integer boundShopSuperiorsPoints; private Integer purchaseLimit; } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Goods.java
@@ -62,25 +62,10 @@ @TableField("detail") private String detail; @ApiModelProperty(value = "运营成本") @TableField("operating_cost") private BigDecimal operatingCost; @ApiModelProperty(value = "门店成本") @TableField("shop_cost") private BigDecimal shopCost; @ApiModelProperty(value = "划线价") @TableField("original_price") private BigDecimal originalPrice; @ApiModelProperty(value = "现金支付(0=否,1=是)") @TableField("cash_payment") private Integer cashPayment; @ApiModelProperty(value = "积分支付(0=否,1=是)") @TableField("point_payment") private Integer pointPayment; @ApiModelProperty(value = "基础售价") @TableField("selling_price") @@ -93,10 +78,6 @@ @ApiModelProperty(value = "销量") @TableField("sale_num") private Integer saleNum; @ApiModelProperty(value = "商品权限 逗号分隔(-1=全部,0=游客,1=普通会员,2=黄金会员,3=钻石会员,4=准代理,5=代理,6=总代,7=合伙人)") @TableField("commodity_authority") private String commodityAuthority; @ApiModelProperty(value = "删除(0=否,1=是)") @TableField("del_flag") @@ -114,21 +95,12 @@ @TableField("sort") private Integer sort; @TableField(exist = false) private Integer vipId; @TableField(exist = false) @ApiModelProperty(value = "指定门店") private GoodsShop goodsShop; @TableField(exist = false) private String categoryName; @TableField(exist = false) private Integer showStatus; @TableField(exist = false) private String payMethod; @ApiModelProperty(value = "经度") @TableField(exist = false) ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopBalanceStatement.java
@@ -66,10 +66,7 @@ @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") ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/ShopWithdraw.java
New file @@ -0,0 +1,90 @@ 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 io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; /** * <p> * * </p> * * @author luodangjia * @since 2024-11-20 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_shop_withdraw") @ApiModel(value="ShopWithdraw对象", description="") public class ShopWithdraw implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "主键") @TableId("id") private Long id; @TableField(exist = false) private String idStr; @ApiModelProperty(value = "门店id") @TableField("shop_id") private Integer shopId; @ApiModelProperty(value = "提现金额") @TableField("money") private BigDecimal money; @ApiModelProperty(value = "审核状态(0=待审核,1=审核通过,2=审核失败)") @TableField("audit_status") private Integer auditStatus; @ApiModelProperty(value = "审核人id") @TableField("audit_user_id") private Long auditUserId; @ApiModelProperty(value = "审核时间") @TableField("audit_time") private LocalDateTime auditTime; @ApiModelProperty(value = "审核结果") @TableField("audit_msg") private String auditMsg; @ApiModelProperty(value = "状态(1=申请中,2=已到账,3=失败)") @TableField("status") private Integer status; @ApiModelProperty(value = "处理结果") @TableField("remark") private String remark; @ApiModelProperty(value = "到账时间") @TableField("arrival_time") private LocalDateTime arrivalTime; @ApiModelProperty(value = "删除(0=否,1=是)") @TableField("del_flag") private Integer delFlag; @ApiModelProperty(value = "添加时间") @TableField("create_time") private LocalDateTime createTime; @ApiModelProperty(value = "添加用户id") @TableField("create_user_id") private Long createUserId; @ApiModelProperty(value = "门店名称") @TableField(exist = false) private String shopName; } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsEvaluateClientFallbackFactory.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.other.api.factory; import com.ruoyi.common.core.domain.R; import com.ruoyi.other.api.domain.GoodsEvaluate; import com.ruoyi.other.api.feignClient.GoodsEvaluateClient; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FallbackFactory; /** * @author zhibing.pu * @Date 2024/11/27 19:57 */ @Slf4j public class GoodsEvaluateClientFallbackFactory implements FallbackFactory<GoodsEvaluateClient> { @Override public GoodsEvaluateClient create(Throwable cause) { return new GoodsEvaluateClient(){ @Override public R<Long> getEvaluateIdByUserIdAndGoodId(Integer goodId, Long userId) { return R.fail("根据用户id和门店id获取评论id失败:" + cause.getMessage()); } }; } } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/GoodsEvaluateClient.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.other.api.feignClient; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.other.api.domain.Goods; import com.ruoyi.other.api.domain.GoodsEvaluate; import com.ruoyi.other.api.factory.GoodsClientFallbackFactory; import com.ruoyi.other.api.factory.GoodsEvaluateClientFallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; import java.util.List; /** * @author zhibing.pu * @Date 2024/11/27 19:56 */ @FeignClient(contextId = "GoodsEvaluateClient", value = ServiceNameConstants.OTHER_SERVICE, fallbackFactory = GoodsEvaluateClientFallbackFactory.class) public interface GoodsEvaluateClient { /** * 通过用户id和商品id查询评价id */ @GetMapping("/getEvaluateIdByUserIdAndGoodId") R<Long> getEvaluateIdByUserIdAndGoodId(@RequestParam("goodId") Integer goodId, @RequestParam("userId") Long userId); } ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -8,5 +8,6 @@ com.ruoyi.other.api.factory.PointSettingClientFallbackFactory com.ruoyi.other.api.factory.RegionClientFallbackFactory com.ruoyi.other.api.factory.ShopBalanceStatementClientFallbackFactory com.ruoyi.other.api.factory.GoodsEvaluateClientFallbackFactory ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/UserApplyForAdmissionController.java
@@ -26,8 +26,8 @@ @PostMapping("/apply") @ApiOperation(value = "入驻申请", tags = {"小程序-个人中心首页-申请合作"}) public R apply(ApplyForAdmissionDTO applyForAdmissionDTO) { userApplyForAdmissionService.apply(applyForAdmissionDTO); return R.ok(); return userApplyForAdmissionService.apply(applyForAdmissionDTO); } @GetMapping("/read") ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/UserApplyForAdmissionService.java
@@ -4,9 +4,10 @@ import com.ruoyi.account.api.model.AppUser; import com.ruoyi.account.api.model.ApplyForAdmission; import com.ruoyi.account.dto.ApplyForAdmissionDTO; import com.ruoyi.common.core.domain.R; public interface UserApplyForAdmissionService extends IService<ApplyForAdmission> { void apply(ApplyForAdmissionDTO applyForAdmissionDTO); R apply(ApplyForAdmissionDTO applyForAdmissionDTO); ApplyForAdmission read(); } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/UserApplyForAdmissionServiceImpl.java
@@ -7,13 +7,20 @@ import com.ruoyi.account.dto.ApplyForAdmissionDTO; import com.ruoyi.account.mapper.AppUserMapper; import com.ruoyi.account.mapper.ApplyForAdmissionMapper; import com.ruoyi.account.service.AppUserService; import com.ruoyi.account.service.UserApplyForAdmissionService; import com.ruoyi.account.util.tencentMap.TencentMapUtil; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.other.api.domain.Region; import com.ruoyi.other.api.feignClient.RegionClient; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.LocalDateTime; @Slf4j @@ -23,19 +30,44 @@ private TokenService tokenService; @Autowired private ApplyForAdmissionMapper userApplyForAdmissionMapper; @Autowired private AppUserService appUserService; @Resource private RegionClient regionClient; /** * 申请入驻 */ @Override public void apply(ApplyForAdmissionDTO applyForAdmissionDTO) { public R apply(ApplyForAdmissionDTO applyForAdmissionDTO) { Long userid = tokenService.getLoginUserApplet().getUserid(); AppUser appUser = appUserService.getOne(new LambdaQueryWrapper<AppUser>().eq(AppUser::getDelFlag, 0).ne(AppUser::getStatus, 3) .eq(AppUser::getPhone, applyForAdmissionDTO.getPhone())); if (appUser == null){ return R.fail("该手机号未注册"); } ApplyForAdmission applyForAdmission = new ApplyForAdmission(); BeanUtils.copyProperties(applyForAdmissionDTO, applyForAdmission); applyForAdmission.setCreateTime(LocalDateTime.now()); applyForAdmission.setApplyUserId(userid); applyForAdmission.setStatus(0); String city = TencentMapUtil.inverseGeographicalAnalysis(applyForAdmission.getLongitude(), applyForAdmission.getLatitude(), false); if(!StringUtils.hasLength(city)){ city = "510100"; } applyForAdmission.setProvinceCode(city.substring(0, 2) + "0000"); Region provinceRegion = regionClient.getRegionBiCode(applyForAdmission.getProvinceCode()).getData(); applyForAdmission.setCityCode(city.substring(0, 4) + "00"); Region cityRegion = regionClient.getRegionBiCode(applyForAdmission.getCityCode()).getData(); applyForAdmission.setDistrictCode(city); Region districtRegion = regionClient.getRegionBiCode(applyForAdmission.getDistrictCode()).getData(); applyForAdmission.setProvince(provinceRegion.getName()); applyForAdmission.setCity(cityRegion.getName()); applyForAdmission.setDistrict(districtRegion.getName()); this.save(applyForAdmission); return R.ok(); } /** @@ -44,6 +76,10 @@ @Override public ApplyForAdmission read() { Long userid = tokenService.getLoginUserApplet().getUserid(); return userApplyForAdmissionMapper.selectOne(new LambdaQueryWrapper<ApplyForAdmission>().eq(ApplyForAdmission::getApplyUserId, userid)); return userApplyForAdmissionMapper .selectOne(new LambdaQueryWrapper<ApplyForAdmission>() .eq(ApplyForAdmission::getApplyUserId, userid) .orderByDesc(ApplyForAdmission::getCreateTime) // 按申请日期降序 .last("LIMIT 1")); } } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.account.api.feignClient.AppUserClient; import com.ruoyi.account.api.model.AppUser; import com.ruoyi.common.core.constant.ExpressCompanyMap; @@ -167,10 +168,28 @@ @ApiImplicitParam(value = "订单id", name = "id", required = true, dataType = "String"), }) @GetMapping("/writeOff") public R<Void> writeOff(String code, Integer shopId, String technicianId) { orderService.writeOff(code, shopId, technicianId); public R<Void> writeOff(String code, Integer shopId) { orderService.writeOff(code, shopId); return R.ok(); } @GetMapping("/getShopOrderList") @ApiOperation(value = "获取订单列表", tags = {"门店后台-订单管理", }) public R<IPage<OrderPageListVo>> getShopOrderList(@ApiParam("模糊查询:订单编号/商品名/手机号 ") String content , @ApiParam("订单状态") Integer status, @ApiParam("门店id") Integer shopId, @ApiParam("页码") @RequestParam("pageNum") Integer pageNum, @ApiParam("每一页数据大小") @RequestParam("pageSize") Integer pageSize) { return R.ok(orderService.getShopOrderList(content,status,shopId,pageNum,pageSize)); } @PutMapping("/shopCancelOrder/{orderId}") @ApiOperation(value = "取消订单", tags = {"门店后台-订单管理"}) public R shopCancelOrder(@PathVariable("orderId") Long orderId) { return orderService.shopCancelOrder(orderId); } /** * 取消订单 @@ -291,7 +310,7 @@ @GetMapping("/getOrderPageList") // @ApiOperation(value = "获取订单列表", tags = {"管理后台-订单管理", "门店后台-订单管理"}) @ApiOperation(value = "获取订单列表", tags = {"管理后台-订单管理", }) public R<PageInfo<OrderPageListVo>> getOrderPageList(OrderPageList orderPageList) { return R.ok(orderService.getOrderPageList(orderPageList)); } @@ -570,8 +589,8 @@ if (StringUtils.isNotEmpty(goodJson) && !"NULL".equals(goodJson)) { Goods goods = JSONObject.parseObject(goodJson, Goods.class); orderExport.setGoodsName(goods.getName()); orderExport.setCompanyCostPrice(goods.getOperatingCost()); orderExport.setSupplierCostPrice(goods.getShopCost()); /* orderExport.setCompanyCostPrice(goods.getOperatingCost()); orderExport.setSupplierCostPrice(goods.getShopCost());*/ } String expressJson = orderExport.getExpressJson(); ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
@@ -1,5 +1,6 @@ package com.ruoyi.order.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.page.PageInfo; @@ -26,7 +27,7 @@ boolean check(Order order, Integer shopId, Long userId); void writeOff(String id,Integer shopId, String technicianId); void writeOff(String id,Integer shopId); /** @@ -123,4 +124,8 @@ * 定时任务关闭订单 */ void closeOrder(); IPage<OrderPageListVo> getShopOrderList(String content, Integer status, Integer shopId, Integer pageNum, Integer pageSize); R shopCancelOrder(Long orderId); } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -5,6 +5,9 @@ import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.api.feignClient.*; import com.ruoyi.account.api.model.*; @@ -110,6 +113,9 @@ private ShopBalanceStatementClient shopBalanceStatementClient; @Resource private GoodsEvaluateClient goodsEvaluateClient; @Resource private SystemConfigClient systemConfigClient; @Resource @@ -141,19 +147,25 @@ Goods goods = JSONObject.parseObject(goodJson, Goods.class); OrderGoodsVO orderGoodsVO = new OrderGoodsVO(); BeanUtils.copyProperties(orderGood, orderGoodsVO); orderGoodsVO.setGoodsId(goods.getId()); orderGoodsVO.setGoodsName(goods.getName()); orderGoodsVO.setGoodsPic(goods.getHomePagePicture()); orderGoodsVO.setNum(order.getNum()); orderGoodsVO.setSellingPrice(goods.getSellingPrice()); orderGoodsVO.setIntegral(goods.getIntegral()); orderGoodsVO.setOriginalPrice(goods.getOriginalPrice()); OrderDetailVO orderDetailVO = new OrderDetailVO(); orderDetailVO.setOrderGoodsVO(orderGoodsVO); Shop shop = shopR.getData(); orderDetailVO.setId(order.getId()); orderDetailVO.setOrderStatus(order.getOrderStatus()); orderDetailVO.setPoint(order.getPoint()); orderDetailVO.setPoint(order.getPoint());//使用的积分 orderDetailVO.setOrderNumber(order.getOrderNumber()); orderDetailVO.setCreateTime(order.getCreateTime()); orderDetailVO.setTotalAmount(order.getTotalAmount()); orderDetailVO.setPointDeductionAmount(order.getPointDeductionAmount());//积分抵扣金额 orderDetailVO.setPaymentAmount(order.getPaymentAmount()); orderDetailVO.setShopName(shop.getName()); orderDetailVO.setShopAddress(shop.getAddress()); @@ -168,6 +180,10 @@ e.printStackTrace(); throw new ServiceException("生成核销码失败"); } //该商品是否被用户评论 Long evaluateId = goodsEvaluateClient.getEvaluateIdByUserIdAndGoodId(goods.getId(), order.getAppUserId()).getData(); orderDetailVO.setEvaluateId(evaluateId); return orderDetailVO; } @@ -183,13 +199,16 @@ @Override @Transactional(rollbackFor = Exception.class) public void writeOff(String id, Integer shopId, String technicianId) { public void writeOff(String id, Integer shopId) { LoginUser loginUserApplet = tokenService.getLoginUserApplet(); Order order = orderMapper.selectById(id); boolean check = check(order, shopId, loginUserApplet.getUserid()); if (!check) { if (order == null) { throw new ServiceException("订单不存在"); } if (!order.getShopId().equals(shopId)) { throw new ServiceException("该订单与当前扫码门店不一致"); } // 售后设置 R<BaseSetting> baseSettingR = baseSettingClient.getBaseSetting(5); @@ -207,10 +226,11 @@ order.setAfterSaleTime(LocalDateTime.now().plusDays(days)); order.setEndTime(LocalDateTime.now()); order.setCancellerAppUserId(loginUserApplet.getUserid()); if (StringUtils.isNotEmpty(technicianId) && !"null".equals(technicianId)) { // order.setTechnicianId(Integer.valueOf(technicianId)); } orderMapper.updateById(order); //店铺可用金额增加 Shop shop = shopClient.getShopById(shopId).getData(); shop.setCanWithdrawMoney(shop.getCanWithdrawMoney().add(order.getTotalAmount())); shopClient.updateShop(shop); } @@ -222,7 +242,7 @@ */ @Override public PageInfo<OrderPageListVo> getOrderPageList(OrderPageList orderPageList) { Long userid = tokenService.getLoginUser().getUserid(); /* Long userid = tokenService.getLoginUser().getUserid(); SysUser sysUser = sysUserClient.getSysUser(userid).getData(); if (2 == sysUser.getRoleType()) { orderPageList.setShopId(sysUser.getObjectId()); @@ -290,7 +310,8 @@ } } return pageInfo.setRecords(list); return pageInfo.setRecords(list);*/ return null; } /** @@ -626,13 +647,20 @@ confirmOrderVo.setCash(good.getSellingPrice()); confirmOrderVo.setPoint(good.getIntegral()); //计算活动价格信息 Price price = getPrice(goodId); if (null != price) { confirmOrderVo.setCash(price.getCash()); confirmOrderVo.setOrderPoint(price.getPoint()); confirmOrderVo.setEndTimeStamp(price.getEndTimeStamp()); //是否在秒杀活动中 GetSeckillActivityInfo info = new GetSeckillActivityInfo(); info.setGoodsId(goodId); GoodsSeckill goodsSeckill = seckillActivityInfoClient.getSeckillActivityInfo(info).getData(); if (null != goodsSeckill){ SeckillActivityInfo activityInfo = seckillActivityInfoClient.getSeckillActivityInfoById(goodsSeckill.getSeckillActivityInfoId()).getData(); //价格 confirmOrderVo.setCash(goodsSeckill.getSellingPrice());//秒杀活动价格 confirmOrderVo.setPoint(goodsSeckill.getIntegral());//秒杀活动积分价格 confirmOrderVo.setPurchaseLimitNum(activityInfo.getMaxNum());//限购数量 } //判断是否是积分支付 if (type == 1) {//现金 confirmOrderVo.setOrderMoney(confirmOrderVo.getCash()); @@ -980,6 +1008,69 @@ } @Override public IPage<OrderPageListVo> getShopOrderList(String content, Integer status, Integer shopId, Integer pageNum, Integer pageSize) { // 创建分页对象 Page<Order> page = new Page<>(pageNum, pageSize); // 构建查询条件 QueryWrapper<Order> queryWrapper = new QueryWrapper<>(); // 添加门店ID条件 if (shopId != null) { queryWrapper.eq("shop_id", shopId); } // 添加订单状态条件 if (status != null) { queryWrapper.eq("order_status", status); } // 模糊查询条件 if (StringUtils.isNotBlank(content)) { // 构建OR条件组:订单编号/商品名/手机号 queryWrapper.and(wrapper -> wrapper .like("order_number", content) // 订单编号 .or() .like("goods_name", content) // 商品名 .or() .inSql("app_user_id", "select id from t_app_user where phone like '%" + content + "%'") // 手机号 ); } // 执行分页查询 IPage<Order> orderPage = orderMapper.selectPage(page, queryWrapper); // 转换为VO对象 return orderPage.convert(this::convertToOrderListVo); } @Override public R shopCancelOrder(Long orderId) { Order order = this.getById(orderId); if (Arrays.asList(5, 6, 7).contains(order.getOrderStatus())) { return R.fail("无效的操作"); } if (null != order.getAfterSaleTime() && LocalDateTime.now().isAfter(order.getAfterSaleTime())) { return R.fail("订单取消失败"); } order.setOrderStatus(5); R r = refundPayMoney(order); if (200 == r.getCode()) { this.updateById(order); } return r; } private OrderPageListVo convertToOrderListVo(Order order) { OrderPageListVo vo = new OrderPageListVo(); // 复制属性 BeanUtils.copyProperties(order, vo); // 查询用户信息 AppUser user = appUserClient.getAppUserById(order.getAppUserId()); if (user != null) { vo.setPhone(user.getPhone()); } return vo; } public String getNumber(Integer size){ StringBuilder str = new StringBuilder(); for (int i = 0; i < size; i++) { @@ -987,27 +1078,7 @@ } return str.toString(); } /** * 根据商品的价格配置体系获取商品当前的价格 */ 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 ){ 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/vo/OrderPageListVo.java
@@ -1,5 +1,6 @@ package com.ruoyi.order.vo; import com.baomidou.mybatisplus.annotation.TableField; import com.ruoyi.common.core.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -18,66 +19,30 @@ private String id; @ApiModelProperty("订单编号") @Excel(name = "订单编号") private String code; @ApiModelProperty("订单状态(1待发货2待收货3待使用4已完成5已取消6已退款7售后中8已评价)") @Excel(name = "订单状态", readConverterExp = "1=待发货,2=待收货,3=待使用,4=已完成,5=已取消,6=已退款,7=售后中,8=已评价") private Integer status; private String orderNumber; @ApiModelProperty("订单状态(3待使用4已完成5已取消6已退款7售后中8已评价)") @Excel(name = "订单状态", readConverterExp = "3=待使用,4=已完成,5=已取消,6=已退款,7=售后中,8=已评价") private Integer orderStatus; @ApiModelProperty("下单时间") @Excel(name = "下单时间") private String createTime; @ApiModelProperty(value = "商品名称(多个名称逗号隔开))") private String goodName; @ApiModelProperty(value = "商品封面(多张逗号隔开,最多三张))") private String goodPics; @ApiModelProperty(value = "订单总金额") private BigDecimal totalAmount; @ApiModelProperty(value = "商品数量") private Integer num; @ApiModelProperty(value = "用户手机号") private String phone; @ApiModelProperty("售后截止时间") private String afterSaleTime; @ApiModelProperty("下单用户") @Excel(name = "下单用户") private String userName; @ApiModelProperty("联系电话") @Excel(name = "联系方式") private String phone; @ApiModelProperty("商品类型(1=服务,2=单品)") @Excel(name = "订单类型", readConverterExp = "1=服务,2=单品") private Integer goodsType; @ApiModelProperty("支付方式(1=微信,2=余额,3=积分)") private Integer paymentType; @ApiModelProperty("订单金额") @Excel(name = "支付金额") private BigDecimal orderMoney; @ApiModelProperty("订单积分") private BigDecimal point; @ApiModelProperty("配送方式(1=自提,2=快递)") private Integer distributionMode; @ApiModelProperty("获得分佣") private BigDecimal getCommission; // 快递单号 @Excel(name = "快递单号") private String expressNum; // 快递公司 @Excel(name = "快递公司") private String expressCompany; // 省 @Excel(name = "省") private String deliverProvince; // 市 @Excel(name = "省区划代码") private String deliverProvinceCode; // 省区划代码 @Excel(name = "市") private String deliverCity; // 市区划代码 @Excel(name = "市区划代码") private String deliverCityCode; /** * 用户id */ private Long appUserId; @ApiModelProperty("售后订单id") private String refundPassId; private Integer shopId; private String expressJson; public BigDecimal getGetPoint(){ return point; } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/GoodsCategoryController.java
@@ -92,7 +92,7 @@ return R.ok(indexlist); } @GetMapping("/list") @ApiOperation(value = "商品分类列表", tags = {"小程序-商城-商城-首页-筛选"}) @ApiOperation(value = "商品分类列表", tags = {"小程序-商城-商城-首页-筛选","门店后台-添加商品"}) public R<List<GoodsCategory>> list(){ return R.ok(goodsCategoryService.list(new LambdaQueryWrapper<GoodsCategory>().eq(GoodsCategory::getDelFlag, 0))); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/GoodsController.java
@@ -10,6 +10,7 @@ import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.redis.annotation.DistributedLock; import com.ruoyi.other.api.domain.Goods; import com.ruoyi.other.dto.AddGoodsDTO; import com.ruoyi.other.service.GoodsService; import com.ruoyi.other.vo.GoodsVO; import io.swagger.annotations.*; @@ -33,16 +34,20 @@ @Resource private GoodsService goodsService; /** * 添加商品 */ @PostMapping("/addGoods") @ApiOperation(value = "发布商品", tags = {"管理后台-商品管理"}) public R<Void> addGoods(@RequestBody Goods goods) { if(goods.getPurchaseLimit()==null){ /* if(goods.getPurchaseLimit()==null){ goods.setPurchaseLimit(-1); } goodsService.addGoods(goods); goodsService.addGoods(goods);*/ return R.ok(); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/GoodsEvaluateController.java
@@ -14,6 +14,7 @@ import com.ruoyi.order.model.Order; import com.ruoyi.other.api.domain.Goods; import com.ruoyi.other.api.domain.GoodsEvaluate; import com.ruoyi.other.mapper.GoodsEvaluateMapper; import com.ruoyi.other.service.GoodsEvaluateService; import com.ruoyi.other.service.GoodsService; import com.ruoyi.other.vo.GoodsEvaluateVO; @@ -43,6 +44,8 @@ @Resource private GoodsEvaluateService goodsEvaluateService; @Resource private GoodsEvaluateMapper goodsEvaluateMapper; @Resource private AppUserClient appUserClient; @Resource private GoodsService goodsService; @@ -52,7 +55,19 @@ private OrderClient orderClient; /** * 通过用户id和商品id查询评价id */ @GetMapping("/getEvaluateIdByUserIdAndGoodId") public R<Long> getEvaluateIdByUserIdAndGoodId(@RequestParam("goodId") Integer goodId, @RequestParam("userId") Long userId) { GoodsEvaluate evaluate = goodsEvaluateMapper.selectOne(new LambdaQueryWrapper<GoodsEvaluate>() .eq(GoodsEvaluate::getGoodsId, goodId).eq(GoodsEvaluate::getAppUserId, userId)); if (evaluate != null) { return R.ok(evaluate.getId()); } return R.ok(null); } @GetMapping("/goodsList") @ApiOperation(value = "获取商品评价", tags = {"小程序-获取商品评价"}) @@ -187,7 +202,7 @@ * 评论详情 */ @GetMapping("/{id}") @ApiOperation(value = "评论详情", tags = {"管理后台-商品管理-评价管理"}) @ApiOperation(value = "评论详情", tags = {"管理后台-商品管理-评价管理","门店后台-订单-查看用户评价详情"}) public R<GoodsEvaluate> getDetail(@PathVariable("id") Long id){ GoodsEvaluate goodsEvaluate = goodsEvaluateService.getById(id); buildDetail(goodsEvaluate); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopController.java
@@ -3,12 +3,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.ruoyi.account.api.feignClient.AppUserClient; import com.ruoyi.account.api.model.AppUser; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.utils.MD5Generator; import com.ruoyi.common.security.utils.SecurityUtils; @@ -16,6 +19,7 @@ import com.ruoyi.order.vo.OrderSaleNum; import com.ruoyi.order.vo.VerifiableShopVo; import com.ruoyi.other.api.domain.*; import com.ruoyi.other.dto.AddGoodsDTO; import com.ruoyi.other.enums.PhoneType; import com.ruoyi.other.mapper.ShopMapper; import com.ruoyi.other.mapper.ShopScoreMapper; @@ -31,6 +35,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.models.auth.In; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -40,7 +46,10 @@ import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.YearMonth; import java.util.*; import java.util.stream.Collectors; @@ -564,8 +573,6 @@ /** * 根据id获取门店信息 * @param id * @return */ @ResponseBody @PostMapping("/getShopById") @@ -574,6 +581,9 @@ return R.ok(shop); } /** * 根据店长id获取门店列表 */ @ResponseBody @PostMapping("/getShopByUserId") public R<List<Shop>> getShopByUserId(@RequestParam("id") Long id){ @@ -581,11 +591,8 @@ return R.ok(list); } /** * 根据店铺管理员电话获取门店数据 * @param phone * @return */ @ResponseBody @PostMapping("/getShopByPhone") @@ -594,11 +601,11 @@ return R.ok(one); } @PostMapping("/getShopByUserIds") /* @PostMapping("/getShopByUserIds") public R<List<Shop>> getShopByUserIds(@RequestBody List<Long> userIds){ List<Shop> list = shopService.list(new LambdaQueryWrapper<Shop>().in(Shop::getAppUserId, userIds)); return R.ok(list); } }*/ /** * 根据名称查询门店id @@ -648,7 +655,6 @@ /** * 编辑门店 * @param shop */ @PostMapping("/updateShop") public void updateShop(@RequestBody Shop shop){ @@ -656,56 +662,11 @@ } @ResponseBody @GetMapping("/getVerifiableShop") @ApiOperation(value = "获取可核销门店列表", tags = {"购物车-小程序"}) public R<List<VerifiableShopVo>> getVerifiableShop(String longitude, String latitude, Integer goodsId){ /* String city = TencentMapUtil.inverseGeographicalAnalysis(longitude, latitude, false); if(null == city){ city = "510100"; } city = city.substring(0, 4) + "00"; LambdaQueryWrapper<Shop> wrapper = new LambdaQueryWrapper<Shop>().eq(Shop::getDelFlag, 0).eq(Shop::getStatus, 1).eq(Shop::getCityCode, city); if(null != goodsId){ Goods goods = goodsService.getById(goodsId); if(1 == goods.getType() && 1 == goods.getAppointStore()){ List<Integer> collect = goodsShopService.list(new LambdaQueryWrapper<GoodsShop>().eq(GoodsShop::getGoodsId, goods.getId())) .stream().map(GoodsShop::getShopId).collect(Collectors.toList()); if(collect.size() > 0){ wrapper.in(Shop::getId, collect); } } } List<Shop> list = shopService.list(wrapper); List<VerifiableShopVo> verifiableShopVoList = new ArrayList<>(); for (Shop shop : list) { VerifiableShopVo vo = new VerifiableShopVo(); vo.setId(shop.getId()); vo.setName(shop.getName()); vo.setAddress(shop.getAddress()); vo.setHomePicture(shop.getHomePicture()); Double wgs84 = GeodesyUtil.getDistance(longitude + "," + latitude, shop.getLongitude() + "," + shop.getLatitude()).get("WGS84"); vo.setDistance(wgs84.longValue()); verifiableShopVoList.add(vo); } verifiableShopVoList.sort(new Comparator<VerifiableShopVo>() { @Override public int compare(VerifiableShopVo o1, VerifiableShopVo o2) { return o1.getDistance().compareTo(o2.getDistance()); } }); return R.ok(verifiableShopVoList);*/ return null; } @ResponseBody @GetMapping("/getSysUserShop") @ApiOperation(value = "获取可切换的门店列表", tags = {"门店后台-首页"}) public R<List<VerifiableShopVo>> getSysUserShop(){ public R<List<VerifiableShopVo>> getSysUserShop(@ApiParam("经度") @RequestParam BigDecimal longitude, @ApiParam("纬度") @RequestParam BigDecimal latitude){ Long userid = tokenService.getLoginUser().getUserid(); UserShop userShop = new UserShop(); userShop.setUserId(userid); @@ -719,12 +680,47 @@ VerifiableShopVo vo = new VerifiableShopVo(); vo.setId(shop.getId()); vo.setName(shop.getName()); vo.setHomePicture(shop.getHomePicture()); String address = shop.getProvince() + shop.getCity() + shop.getDistrict()+ shop.getAddress(); vo.setAddress(address); if (null != latitude && null != longitude) { Double wgs84 = GeodesyUtil.getDistance(longitude + "," + latitude, shop.getLongitude() + "," + shop.getLatitude()).get("WGS84"); vo.setDistance(wgs84.longValue()); } list.add(vo); } return R.ok(list); } @ResponseBody @GetMapping("/getShopBalance") @ApiOperation(value = "获取门店余额", tags = {"门店后台-首页"}) public R<ShopBalanceVO> getShopBalance(@ApiParam("门店id") @RequestParam Integer shopId){ return R.ok(shopService.getShopBalance(shopId)); } @ResponseBody @GetMapping("/getShopBalanceStatementList") @ApiOperation(value = "获取门店余额变动明细", tags = {"门店后台-首页"}) public R<PageInfo<ShopBalanceStatementVO>> getShopBalanceStatementList(@ApiParam("变动类型(4=提现,5=订单收入,6=订单退款)") Integer type, @ApiParam("门店id") Integer shopId, @ApiParam("指定日期") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date, Integer pageCurr, Integer pageSize){ LocalDateTime startTime = null; LocalDateTime endTime = null; if (date != null) { // 将 createTime 设置为当天的开始时间 (00:00) startTime = date.atStartOfDay(); // 使用 YearMonth 来获取该月的最后一天 YearMonth yearMonth = YearMonth.from(date); LocalDate lastDayOfMonth = yearMonth.atEndOfMonth(); // 将最后一天转换为 LocalDateTime,并设置为当天的最后一秒 (23:59:59.999) endTime = lastDayOfMonth.atTime(LocalTime.MAX); } return R.ok(shopService.getShopBalanceStatementList(shopId,startTime, endTime, type, pageCurr, pageSize)); } @PostMapping("/saveWithdrawalAccount") @ApiOperation(value = "保存提现账户", tags = {"门店后台-财务统计-提现明细"}) @@ -734,9 +730,8 @@ } @PostMapping("/saveWithdrawalAppletAccount") @ApiOperation(value = "保存提现账户", tags = {"小程序-个人中心-门店管理-门店钱包"}) @ApiOperation(value = "保存提现账户", tags = {"门店后台-首页"}) public R saveWithdrawalAppletAccount(@RequestBody SaveWithdrawalAccount saveWithdrawalAccount){ Shop shop = shopService.getById(saveWithdrawalAccount.getShopId()); if(null != shop){ shop.setReceiverAccountNoEnc(saveWithdrawalAccount.getReceiverAccountNoEnc()); @@ -745,6 +740,69 @@ shop.setReceiverBankChannelNo(saveWithdrawalAccount.getReceiverBankChannelNo()); shopService.updateById(shop); } return R.ok(); } /** * 指定门店商品 */ @ResponseBody @GetMapping("/getGoodsListByShopId") @ApiOperation(value = "获取门店内商品列表", tags = {"门店后台-首页"}) public R<PageInfo<GoodsVO>> getGoodsListByShopId(@ApiParam("门店id") Integer shopId, Integer pageCurr, Integer pageSize) { PageInfo<GoodsVO> pageInfo = new PageInfo<>(pageCurr, pageSize); List<GoodsVO> goodsList = shopService.getGoodsListByShopId(pageInfo, shopId); return R.ok(pageInfo.setRecords(goodsList)); } /** * 商品详情 */ @GetMapping("/goodsDetail/{goodsId}") @ApiOperation(value = "商品详情", tags = {"门店后台-首页"}) public R<GoodsVO> goodsDetail(@PathVariable("goodsId") Long goodsId) { return R.ok(shopService.goodsDetail(goodsId)); } /** * 添加商品 */ @PostMapping("/addGoods") @ApiOperation(value = "发布商品", tags = {"门店后台-商品管理"}) public R<Void> addGoods(@RequestBody AddGoodsDTO addGoodsDTO) { shopService.addGoodsByShop(addGoodsDTO); return R.ok(); } /** * 上、下架商品 */ @PostMapping("/status/{goodsId}") @ApiOperation(value = "上、下架商品", tags = {"门店后台-商品管理"}) public R<Void> status(@PathVariable Integer goodsId) { Goods goods = goodsService.getById(goodsId); if (goods == null) { return R.fail("商品不存在"); } goodsService.update(new UpdateWrapper<Goods>() .setSql("status = CASE status WHEN 1 THEN 2 WHEN 2 THEN 1 ELSE status END") .set("update_time", LocalDateTime.now()) .eq("id", goodsId)); return R.ok(); } /** * 删除商品 */ @DeleteMapping("/del/{goodsId}") @ApiOperation(value = "发布商品", tags = {"门店后台-商品管理"}) public R<Void> addGoods(@PathVariable Integer goodsId) { Goods goods = goodsService.getById(goodsId); if (goods == null) { return R.fail("商品不存在"); } goodsService.removeById(goodsId); return R.ok(); } @@ -761,7 +819,7 @@ @ResponseBody @GetMapping("/verifyAccountConfiguration") @ApiOperation(value = "判断是否有提现账户", tags = {"门店后台-财务管理-提现明细"}) @ApiOperation(value = "判断是否有提现账户", tags = {"门店后台-首页"}) public R verifyAccountConfiguration(){ Long userid = tokenService.getLoginUser().getUserid(); SysUser sysUser = sysUserClient.getSysUser(userid).getData(); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/ShopWithdrawController.java
New file @@ -0,0 +1,345 @@ package com.ruoyi.other.controller; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.api.feignClient.AppUserClient; 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.security.service.TokenService; import com.ruoyi.other.api.domain.Shop; import com.ruoyi.other.api.domain.ShopBalanceStatement; import com.ruoyi.other.api.domain.ShopWithdraw; import com.ruoyi.other.service.ShopBalanceStatementService; import com.ruoyi.other.service.ShopService; import com.ruoyi.other.service.ShopWithdrawService; import com.ruoyi.other.util.payment.TransferUtil; import com.ruoyi.other.util.payment.model.AccountBalanceQueryResult; import com.ruoyi.other.util.payment.model.SinglePay; import com.ruoyi.other.util.payment.model.SinglePayCallbackResult; import com.ruoyi.other.util.payment.model.SinglePayResult; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysUserClient; import com.ruoyi.system.api.model.LoginUser; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * <p> * 前端控制器 * </p> * * @author luodangjia * @since 2024-11-20 */ @RestController @RequestMapping("/shop-withdraw") @Api(tags = {"管理后台-门店管理-提现管理"}) public class ShopWithdrawController { @Resource private ShopWithdrawService shopWithdrawService; @Resource private ShopService shopService; @Resource private TokenService tokenService; @Resource private ShopBalanceStatementService shopBalanceStatementService; @Resource private AppUserClient appUserClient; @Resource private SysUserClient sysUserClient; @GetMapping("/getShopById") @ApiOperation("通过门店id获取账户信息回填") public R<Shop> getShopById(Integer id) { return R.ok(shopService.getById(id)); } /** * 提现申请列表 */ @GetMapping("/list") @ApiOperation("提现申请列表") public R<IPage<ShopWithdraw>> list(@ApiParam("页码") @RequestParam Integer pageNum, @ApiParam("每一页数据大小") Integer pageSize, ShopWithdraw shopWithdraw) { List<Shop> list = shopService.list(new LambdaUpdateWrapper<Shop>() .like(StringUtils.isNotEmpty(shopWithdraw.getShopName()), Shop::getName, shopWithdraw.getShopName()) .eq(Shop::getDelFlag, 0)); List<Integer> collect1 = list.stream().map(Shop::getId).collect(Collectors.toList()); if (CollectionUtils.isEmpty(collect1)){ return R.ok(Page.of(pageNum, pageSize)); } Page<ShopWithdraw> page = shopWithdrawService.page(Page.of(pageNum, pageSize), new LambdaQueryWrapper<ShopWithdraw>() .in(collect1.size() > 0, ShopWithdraw::getShopId, collect1) .orderByDesc(ShopWithdraw::getCreateTime)); List<ShopWithdraw> records = page.getRecords(); List<Integer> collect = records.stream().map(ShopWithdraw::getShopId).collect(Collectors.toList()); List<Shop> shops = null; if(collect.size() > 0){ shops = shopService.listByIds(collect); } for(ShopWithdraw item : records){ Optional<Shop> first = shops.stream().filter(s -> s.getId().equals(item.getShopId())).findFirst(); if(first.isPresent()){ item.setShopName(first.get().getName()); } item.setIdStr(item.getId().toString()); } return R.ok(page); } @GetMapping("/shop/list") @ApiOperation(value = "提现申请列表", notes = "提现申请列表", tags = {"门店后台"}) public R<IPage<ShopWithdraw>> shoplist(@ApiParam("页码") @RequestParam Integer pageNum, @ApiParam("每一页数据大小") Integer pageSize, @ApiParam("门店id")Integer shopId, @ApiParam("审核状态(0=待审核,1=审核通过,2=审核失败)")Integer auditStatus) { Page<ShopWithdraw> page = shopWithdrawService.page(Page.of(pageNum, pageSize), new LambdaQueryWrapper<ShopWithdraw>() .eq(ShopWithdraw::getShopId,shopId) .eq(auditStatus!=null,ShopWithdraw::getAuditStatus,auditStatus) .orderByDesc(ShopWithdraw::getCreateTime) ); page.getRecords().forEach(s->s.setIdStr(s.getId().toString())); return R.ok(page); } @GetMapping("/shop/info") @ApiOperation(value = "提现申请列表上方数据", notes = "提现申请列表", tags = {"门店后台"}) public R<Shop> shopCommissionStatisticsinfo(){ LoginUser loginUser = tokenService.getLoginUser(); SysUser sysUser = sysUserClient.getSysUser(loginUser.getUserid()).getData(); Shop byId = shopService.getById(sysUser.getObjectId()); List<ShopWithdraw> list = shopWithdrawService.lambdaQuery() .eq(ShopWithdraw::getShopId, sysUser.getObjectId()) .list(); if (!list.isEmpty()){ // 待审核列表 List<ShopWithdraw> toBeReviewList = list.stream() .filter(s -> s.getAuditStatus() == 0) .collect(Collectors.toList()); // 审核通过列表 List<ShopWithdraw> passedReviewList = list.stream() .filter(s -> s.getAuditStatus() == 1) .collect(Collectors.toList()); BigDecimal bigDecimal = toBeReviewList.stream().map(ShopWithdraw::getMoney).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); byId.setWithdrawAuditMoney(bigDecimal); BigDecimal bigDecimal1 = passedReviewList.stream().map(ShopWithdraw::getMoney).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); byId.setWithdrawMoney(bigDecimal1); }else { byId.setWithdrawAuditMoney(BigDecimal.ZERO); } return R.ok(byId); } @GetMapping("/shop/with") @ApiOperation(value = "提现申请", notes = "提现申请列表", tags = {"门店后台"}) public R shopwith(@RequestParam BigDecimal money){ LoginUser loginUser = tokenService.getLoginUser(); SysUser sysUser = sysUserClient.getSysUser(loginUser.getUserid()).getData(); baseWithdrawalApplication(money, sysUser.getUserId(), sysUser.getObjectId()); return R.ok(); } /** * 小程序端提现申请 */ @ApiOperation(value = "提现申请", notes = "提现申请", tags = {"门店后台"}) @GetMapping("/withdrawalApplication") @ResponseBody public R withdrawalApplication(@ApiParam("提现金额") @RequestParam BigDecimal money, @ApiParam("门店id")@RequestParam Integer shopId) { LoginUser loginUser = tokenService.getLoginUserApplet(); baseWithdrawalApplication(money, loginUser.getUserid(), shopId); return R.ok(); } private void baseWithdrawalApplication(BigDecimal money, Long userId, Integer shopId) { Shop shop = shopService.getById(shopId); if (money.compareTo(BigDecimal.ZERO)==0){ throw new ServiceException("提现金额必须大于零"); } if (money.compareTo(shop.getCanWithdrawMoney())>0){ throw new ServiceException("提现金额不能大于可提现金额"); } if(StringUtils.isEmpty(shop.getReceiverAccountNoEnc())){ throw new ServiceException("请完善账户信息后再申请提现!"); } ShopWithdraw shopWithdraw = new ShopWithdraw(); shopWithdraw.setShopId(shopId); shopWithdraw.setMoney(money); shopWithdraw.setAuditStatus(0);//待审核 shopWithdraw.setStatus(1);//申请中 shopWithdraw.setCreateTime(LocalDateTime.now()); shopWithdrawService.save(shopWithdraw); //扣除账户余额及添加变动明细 BigDecimal balance = shop.getBalance();//余额 BigDecimal canWithdrawMoney = shop.getCanWithdrawMoney();//可提现金额 BigDecimal withdrawMoney = shop.getWithdrawMoney();//审核中金额 shop.setBalance(balance.subtract(money).setScale(2, RoundingMode.HALF_EVEN));//余额减少 shop.setCanWithdrawMoney(canWithdrawMoney.subtract(money).setScale(2, RoundingMode.HALF_EVEN));//可提现金额减少 shop.setWithdrawMoney(withdrawMoney.add(money).setScale(2, RoundingMode.HALF_EVEN));//审核中金额增加 shopService.updateById(shop); //添加余额变动明细 ShopBalanceStatement shopBalanceStatement = new ShopBalanceStatement(); shopBalanceStatement.setShopId(shop.getId()); shopBalanceStatement.setType(4); shopBalanceStatement.setHistoricalBalance(balance); shopBalanceStatement.setVariableAmount(money); shopBalanceStatement.setBalance(shop.getBalance()); shopBalanceStatement.setCreateUserId(userId); shopBalanceStatement.setCreateTime(LocalDateTime.now()); shopBalanceStatement.setObjectId(shopWithdraw.getId()); shopBalanceStatementService.save(shopBalanceStatement); } /** * 审核 */ @PostMapping("/audit") @ApiOperation("审核") public R<Void> audit(@RequestBody ShopWithdraw shopWithdraw) { LoginUser loginUser = tokenService.getLoginUser(); ShopWithdraw shopWithdraw1 = shopWithdrawService.getById(shopWithdraw.getId()); if(0 != shopWithdraw1.getAuditStatus()){ return R.fail("不能重复审核"); } Shop shop = shopService.getById(shopWithdraw1.getShopId()); BigDecimal money = shopWithdraw1.getMoney(); if(1 == shopWithdraw.getAuditStatus()){ //先检查账户余额是否充足 AccountBalanceQueryResult accountBalanceQueryResult = TransferUtil.accountBalanceQuery(); if(null == accountBalanceQueryResult){ return R.fail("查询账户余额出错"); } Double useAbleSettAmount = accountBalanceQueryResult.getUseAbleSettAmount(); if(useAbleSettAmount < (shopWithdraw1.getMoney().doubleValue() + 1)){ return R.fail("账户可用余额不足,请先补充账户余额"); } //银行卡转账 SinglePay singlePay = new SinglePay(); singlePay.setTradeMerchantNo(TransferUtil.sysTradeMerchantNo); singlePay.setMerchantOrderNo(shopWithdraw1.getId().toString()); singlePay.setReceiverAccountNoEnc(shop.getReceiverAccountNoEnc()); singlePay.setReceiverNameEnc(shop.getReceiverNameEnc()); singlePay.setReceiverAccountType(shop.getReceiverAccountType()); singlePay.setReceiverBankChannelNo(shop.getReceiverBankChannelNo()); singlePay.setPaidAmount(shopWithdraw1.getMoney().doubleValue()); singlePay.setPaidDesc("账户余额提现"); singlePay.setPaidUse("208"); singlePay.setCallbackUrl("/other/shop-withdraw/withdrawalCallback"); SinglePayResult singlePayResult = TransferUtil.singlePay(singlePay); if(null == singlePayResult){ return R.fail("转账失败"); } shopWithdraw1.setStatus(1); } if(2 == shopWithdraw.getAuditStatus()){ //回退金额和添加变动明细 BigDecimal balance = shop.getBalance(); BigDecimal canWithdrawMoney = shop.getCanWithdrawMoney(); BigDecimal withdrawMoney = shop.getWithdrawMoney(); shop.setBalance(balance.add(money).setScale(2, RoundingMode.HALF_EVEN)); shop.setCanWithdrawMoney(canWithdrawMoney.add(money).setScale(2, RoundingMode.HALF_EVEN)); shop.setWithdrawMoney(withdrawMoney.subtract(money).setScale(2, RoundingMode.HALF_EVEN)); shopService.updateById(shop); //添加门店变动明细 ShopBalanceStatement shopBalanceStatement = new ShopBalanceStatement(); shopBalanceStatement.setShopId(shop.getId()); shopBalanceStatement.setType(4); shopBalanceStatement.setHistoricalBalance(balance); shopBalanceStatement.setVariableAmount(money); shopBalanceStatement.setBalance(shop.getBalance()); shopBalanceStatement.setCreateUserId(loginUser.getUserid()); shopBalanceStatement.setCreateTime(LocalDateTime.now()); shopBalanceStatement.setObjectId(shopWithdraw.getId()); shopBalanceStatementService.save(shopBalanceStatement); } shopWithdraw1.setAuditStatus(shopWithdraw.getAuditStatus()); shopWithdraw1.setAuditUserId(loginUser.getUserid()); shopWithdraw1.setAuditTime(LocalDateTime.now()); shopWithdraw1.setAuditMsg(shopWithdraw.getAuditMsg()); shopWithdrawService.updateById(shopWithdraw1); return R.ok(); } /** * 提现审核通过后转账回调通知 * @param singlePayCallbackResult */ @ResponseBody @PostMapping("/withdrawalCallback") public Object withdrawalCallback(@RequestBody SinglePayCallbackResult singlePayCallbackResult){ Integer status = singlePayCallbackResult.getStatus(); String merchantOrderNo = singlePayCallbackResult.getMerchantOrderNo(); ShopWithdraw shopWithdraw = shopWithdrawService.getById(merchantOrderNo); if(203 == status || 205 == status){ if(1 == shopWithdraw.getStatus()){ shopWithdraw.setStatus(2); shopWithdraw.setArrivalTime(LocalDateTime.now()); shopWithdrawService.updateById(shopWithdraw); } JSONObject jsonObject = new JSONObject(); jsonObject.put("statusCode", 2001); return jsonObject; }else{ //回退金额和添加变动明细 Shop shop = shopService.getById(shopWithdraw.getShopId()); BigDecimal balance = shop.getBalance(); BigDecimal canWithdrawMoney = shop.getCanWithdrawMoney(); BigDecimal withdrawMoney = shop.getWithdrawMoney(); shop.setBalance(balance.add(shopWithdraw.getMoney()).setScale(2, RoundingMode.HALF_EVEN)); shop.setCanWithdrawMoney(canWithdrawMoney.add(shopWithdraw.getMoney()).setScale(2, RoundingMode.HALF_EVEN)); shop.setWithdrawMoney(withdrawMoney.subtract(shopWithdraw.getMoney()).setScale(2, RoundingMode.HALF_EVEN)); shopService.updateById(shop); //添加门店变动明细 ShopBalanceStatement shopBalanceStatement = new ShopBalanceStatement(); shopBalanceStatement.setShopId(shop.getId()); shopBalanceStatement.setType(4); shopBalanceStatement.setHistoricalBalance(balance); shopBalanceStatement.setVariableAmount(shopWithdraw.getMoney()); shopBalanceStatement.setBalance(shop.getBalance()); shopBalanceStatement.setCreateUserId(shopWithdraw.getAuditUserId()); shopBalanceStatement.setCreateTime(LocalDateTime.now()); shopBalanceStatement.setObjectId(shopWithdraw.getId()); shopBalanceStatementService.save(shopBalanceStatement); shopWithdraw.setStatus(3); shopWithdraw.setRemark(singlePayCallbackResult.getErrorCodeDesc()); shopWithdrawService.updateById(shopWithdraw); JSONObject jsonObject = new JSONObject(); jsonObject.put("statusCode", 2001); return jsonObject; } } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/dto/AddGoodsDTO.java
New file @@ -0,0 +1,63 @@ package com.ruoyi.other.dto; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; @Data public class AddGoodsDTO { @ApiModelProperty(value = "门店id") private Integer shopId; @ApiModelProperty(value = "名称") private String name; @ApiModelProperty(value = "分类id") private Integer goodsCategoryId; @ApiModelProperty(value = "限购数量(-1不限购)") private Integer purchaseLimit; @ApiModelProperty(value = "商品简介") private String introduction; @ApiModelProperty(value = "封面图") private String homePagePicture; @ApiModelProperty(value = "详情图,多个逗号分隔") private String detailPicture; @ApiModelProperty(value = "商品详情") private String detail; @ApiModelProperty(value = "划线价") private BigDecimal originalPrice; @ApiModelProperty(value = "基础售价") private BigDecimal sellingPrice; @ApiModelProperty(value = "是否秒杀活动(0-否,1-是)") private Integer isActivity; @ApiModelProperty(value = "活动开始时间") private LocalDateTime startTime; @ApiModelProperty(value = "活动结束时间") private LocalDateTime endTime; @ApiModelProperty(value = "活动价格") private BigDecimal activityPrice; @ApiModelProperty(value = "活动限购数量") private Integer maxNum; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/ShopBalanceStatementMapper.java
@@ -2,9 +2,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.other.api.domain.ShopBalanceStatement; import com.ruoyi.other.vo.ShopBalanceStatementVO; import org.apache.ibatis.annotations.Param; import java.time.LocalDateTime; import java.util.List; /** @@ -22,4 +25,6 @@ List<ShopBalanceStatement> selectShopBalanceStatementList(@Param("bs") ShopBalanceStatement shopBalanceStatement); List<ShopBalanceStatementVO> getShopBalanceStatementList(PageInfo<ShopBalanceStatementVO> pageInfo, @Param("shopId") Integer shopId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime, @Param("type") Integer type); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/ShopMapper.java
@@ -3,7 +3,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.other.api.domain.Shop; import com.ruoyi.other.vo.GoodsVO; import com.ruoyi.other.vo.NearbyShopVO; import com.ruoyi.other.vo.ShopDetailVO; import com.ruoyi.other.vo.ShopStatistics; @@ -30,4 +32,5 @@ ShopStatistics getShopStatistics(@Param("shopId") Integer shopId); List<GoodsVO> selectListByShopId(PageInfo<GoodsVO> pageInfo, Integer shopId); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/ShopWithdrawMapper.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.other.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.other.api.domain.ShopWithdraw; /** * <p> * Mapper 接口 * </p> * * @author luodangjia * @since 2024-11-20 */ public interface ShopWithdrawMapper extends BaseMapper<ShopWithdraw> { } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/GoodsService.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.other.api.domain.Goods; import com.ruoyi.other.dto.AddGoodsDTO; import com.ruoyi.other.vo.GoodsVO; import java.util.List; ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopService.java
@@ -2,12 +2,15 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.other.api.domain.Shop; import com.ruoyi.other.vo.NearbyShopVO; import com.ruoyi.other.vo.SaveWithdrawalAccount; import com.ruoyi.other.vo.ShopDetailVO; import com.ruoyi.other.api.domain.ShopBalanceStatement; import com.ruoyi.other.dto.AddGoodsDTO; import com.ruoyi.other.vo.*; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; /** @@ -36,4 +39,23 @@ void saveWithdrawalAccount(SaveWithdrawalAccount saveWithdrawalAccount); /** * 店铺余额统计 */ ShopBalanceVO getShopBalance(Integer shopId); /** * 店铺余额变更明细 */ PageInfo<ShopBalanceStatementVO> getShopBalanceStatementList(Integer shopId, LocalDateTime startTime, LocalDateTime endTime, Integer type, Integer pageCurr, Integer pageSize); /** * 店铺内商品列表 门店后台 */ List<GoodsVO> getGoodsListByShopId(PageInfo<GoodsVO> pageInfo, Integer shopId); GoodsVO goodsDetail(Long goodsId); void addGoodsByShop(AddGoodsDTO addGoodsDTO); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/ShopWithdrawService.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.other.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.other.api.domain.ShopWithdraw; /** * <p> * 服务类 * </p> * * @author luodangjia * @since 2024-11-20 */ public interface ShopWithdrawService extends IService<ShopWithdraw> { } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/GoodsServiceImpl.java
@@ -18,6 +18,7 @@ import com.ruoyi.order.feignClient.RemoteOrderGoodsClient; import com.ruoyi.order.vo.Price; import com.ruoyi.other.api.domain.*; import com.ruoyi.other.dto.AddGoodsDTO; import com.ruoyi.other.enums.GoodsStatus; import com.ruoyi.other.mapper.GoodsMapper; import com.ruoyi.other.mapper.GoodsShopMapper; @@ -28,12 +29,14 @@ import com.ruoyi.other.vo.NearbyShopVO; import com.ruoyi.system.api.domain.SysConfig; import com.ruoyi.system.api.feignClient.SysConfigClient; import com.ruoyi.system.api.model.LoginUser; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -92,13 +95,14 @@ for (GoodsVO goods : list) { //计算所需价格和积分 Price price = getPrice( goods.getGoodsId(), 1); Price price = getPrice( goods.getGoodsId()); if(null != price){ //秒杀活动 goods.setSellingPrice(price.getCash()); goods.setIntegral(price.getPoint()); goods.setStartTime(price.getStartTime()); goods.setEndTime(price.getEndTime()); goods.setPurchaseLimit(price.getPurchaseLimit()); } //已售数量 Integer data = orderClient.getGoodsSaleNum(goods.getGoodsId(), 1).getData(); @@ -198,13 +202,14 @@ goodsVO.setGoodsName(goods.getName()); //计算所需价格和积分 Price price = getPrice( goods.getId(), 1); Price price = getPrice( goods.getId()); if(null != price){ //秒杀活动 goodsVO.setSellingPrice(price.getCash()); goodsVO.setIntegral(price.getPoint()); goodsVO.setStartTime(price.getStartTime()); goodsVO.setEndTime(price.getEndTime()); goodsVO.setPurchaseLimit(price.getPurchaseLimit()); } //已售数量 Integer data = orderClient.getGoodsSaleNum(goods.getId(), 1).getData(); @@ -231,11 +236,12 @@ List<GoodsVO> goods = goodsMapper.selectListByShopId(pageInfo, shopId); for (GoodsVO good : goods) { //价格 Price price = getPrice( good.getGoodsId(), 1); Price price = getPrice( good.getGoodsId()); if(null != price){ //秒杀活动 good.setSellingPrice(price.getCash()); good.setIntegral(price.getPoint()); good.setPurchaseLimit(price.getPurchaseLimit()); good.setStartTime(price.getStartTime()); good.setEndTime(price.getEndTime()); } @@ -328,13 +334,11 @@ /** * 根据商品的价格配置体系获取商品当前的价格 * @param goodsId * @param type 1普通商品,2秒杀商品 * @return * 获取商品当前的价格,就是判断是否在秒杀活动中 */ public Price getPrice( Integer goodsId, Integer type){ public Price getPrice( Integer goodsId ){ //判断是否有在秒杀活动时间中 Price price = new Price(); SeckillActivityInfo one = seckillActivityInfoService.getOne(new LambdaQueryWrapper<SeckillActivityInfo>().eq(SeckillActivityInfo::getGoodId, goodsId) @@ -346,7 +350,7 @@ goodsSeckill = goodsSeckillService.getOne(new LambdaQueryWrapper<GoodsSeckill>().eq(GoodsSeckill::getSeckillActivityInfoId, one.getId())); } //没有秒杀活动或者添加的普通商品则使用秒杀活动价格 if(null == goodsSeckill || type == 1){ if(null == goodsSeckill ){ return null; } //秒杀活动价格 @@ -355,6 +359,7 @@ price.setPoint(getPoint(price.getCash())); price.setStartTime(one.getStartTime()); price.setEndTime(one.getEndTime()); price.setPurchaseLimit(one.getMaxNum()); return price; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java
@@ -9,25 +9,28 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.GeodesyUtil; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.bean.BeanUtils; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.other.api.domain.Phone; import com.ruoyi.other.api.domain.Shop; import com.ruoyi.other.api.domain.ShopScore; import com.ruoyi.other.mapper.PhoneMapper; import com.ruoyi.other.mapper.ShopMapper; import com.ruoyi.other.mapper.ShopScoreMapper; import com.ruoyi.other.service.ShopScoreService; import com.ruoyi.other.service.ShopService; import com.ruoyi.other.vo.NearbyShopVO; import com.ruoyi.other.vo.SaveWithdrawalAccount; import com.ruoyi.other.vo.ShopDetailVO; import com.ruoyi.order.feignClient.OrderClient; import com.ruoyi.order.vo.Price; import com.ruoyi.other.api.domain.*; import com.ruoyi.other.dto.AddGoodsDTO; import com.ruoyi.other.enums.GoodsStatus; import com.ruoyi.other.mapper.*; import com.ruoyi.other.service.*; import com.ruoyi.other.vo.*; 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 org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -44,6 +47,8 @@ @Resource private ShopMapper shopMapper; @Resource private GoodsService goodsService; @Resource private PhoneMapper phoneMapper; @Resource private ShopScoreService shopScoreService; @@ -55,6 +60,20 @@ private SysUserClient sysUserClient; @Resource private ShopScoreMapper scoreMapper; @Resource private ShopBalanceStatementMapper shopBalanceStatementMapper; @Resource private OrderClient orderClient; @Resource private SeckillActivityInfoService seckillActivityInfoService; @Resource private GoodsSeckillService goodsSeckillService; @Resource private SysConfigClient sysConfigClient; @Resource private GoodsShopMapper goodsShopMapper; @Resource private GoodsShopService goodsShopService; /** @@ -179,5 +198,217 @@ } } /** * 门店余额统计 * @param shopId * @return */ @Override public ShopBalanceVO getShopBalance(Integer shopId) { Shop shop = shopMapper.selectById(shopId); ShopBalanceVO shopBalanceVO = new ShopBalanceVO(); shopBalanceVO.setBalance(shop.getBalance()); shopBalanceVO.setCanWithdrawMoney(shop.getCanWithdrawMoney()); shopBalanceVO.setWithdrawMoney(shop.getWithdrawMoney()); shopBalanceVO.setWithdrawAuditMoney(shop.getWithdrawAuditMoney()); //冻结金额 = 余额 - 可提现金额 shopBalanceVO.setFreezeMoney(shop.getBalance().subtract(shop.getCanWithdrawMoney())); return shopBalanceVO; } /** * 门店余额变更明细 */ @Override public PageInfo<ShopBalanceStatementVO> getShopBalanceStatementList(Integer shopId, LocalDateTime startTime, LocalDateTime endTime, Integer type, Integer pageCurr, Integer pageSize) { PageInfo<ShopBalanceStatementVO> pageInfo = new PageInfo<>(pageCurr, pageSize); List<ShopBalanceStatementVO> ShopBalanceStatementList = shopBalanceStatementMapper.getShopBalanceStatementList(pageInfo, shopId, startTime, endTime, type); for (ShopBalanceStatementVO shopBalanceStatementVO : ShopBalanceStatementList) { BigDecimal historicalBalance = shopBalanceStatementVO.getHistoricalBalance(); BigDecimal balance = shopBalanceStatementVO.getBalance(); if (historicalBalance != null && balance != null) { shopBalanceStatementVO.setFlag( historicalBalance.compareTo(balance) > 0 ? 2 : 1 ); } } pageInfo.setRecords(ShopBalanceStatementList); return pageInfo; } /** * 店铺内商品列表 门店后台 */ @Override public List<GoodsVO> getGoodsListByShopId(PageInfo<GoodsVO> pageInfo, Integer shopId) { //查询该门店商品 List<GoodsVO> goods = shopMapper.selectListByShopId(pageInfo, shopId); for (GoodsVO good : goods) { //价格 Price price = getPrice( good.getGoodsId()); if(null != price){ //秒杀活动 good.setSellingPrice(price.getCash()); good.setIntegral(price.getPoint()); good.setStartTime(price.getStartTime()); good.setEndTime(price.getEndTime()); good.setPurchaseLimit(price.getPurchaseLimit()); } Integer data = orderClient.getGoodsSaleNum(good.getGoodsId(), 1).getData(); good.setSaleNum(data); } return goods; } @Override public GoodsVO goodsDetail(Long goodsId) { if (goodsId == null || goodsId <= 0) { throw new NullPointerException("商品ID不能为空"); } Goods goods = goodsService.getById(goodsId); if(null == goods || goods.getDelFlag() == 1){ throw new RuntimeException("商品不存在"); } GoodsVO goodsVO = new GoodsVO(); BeanUtils.copyBeanProp(goodsVO, goods); goodsVO.setGoodsId(goods.getId()); goodsVO.setGoodsName(goods.getName()); //计算所需价格和积分 Price price = getPrice( goods.getId()); if(null != price){ //秒杀活动 goodsVO.setSellingPrice(price.getCash()); goodsVO.setIntegral(price.getPoint()); goodsVO.setStartTime(price.getStartTime()); goodsVO.setEndTime(price.getEndTime()); } //已售数量 Integer data = orderClient.getGoodsSaleNum(goods.getId(), 1).getData(); goodsVO.setSaleNum(data); //一个商品对应一个门店 //查找门店 GoodsShop goodsShop = goodsShopMapper.selectOne(new LambdaQueryWrapper<GoodsShop>() .eq(GoodsShop::getGoodsId, goodsId)); Shop shop1 = shopMapper.selectById(goodsShop.getShopId()); ArrayList<Shop> shops = new ArrayList<>(); shops.add(shop1); goodsVO.setShopList(shops); //已售数量 Integer integer = orderClient.getGoodsSaleNum(goods.getId(), 1).getData(); goodsVO.setSaleNum(integer); return goodsVO; } /** * 发布商品 门店后台-商品管理 */ @Override public void addGoodsByShop(AddGoodsDTO addGoodsDTO) { if(addGoodsDTO.getPurchaseLimit()==null){ addGoodsDTO.setPurchaseLimit(-1); } Goods goods = new Goods(); BeanUtils.copyProperties(addGoodsDTO, goods); goods.setSaleNum(0);//销量 goods.setStatus(GoodsStatus.DOWN.getCode());//下架状态 goods.setIntegral(getPoint(addGoodsDTO.getSellingPrice()));//积分 goods.setDelFlag(0); goods.setCreateTime(LocalDateTime.now()); goodsService.save(goods);//添加商品 //保存商品门店关系 GoodsShop goodsShop = new GoodsShop(); goodsShop.setGoodsId(goods.getId()); goodsShop.setShopId(addGoodsDTO.getShopId()); Shop shop = shopMapper.selectById(addGoodsDTO.getShopId()); goodsShop.setShopName(shop.getName()); goodsShop.setOwnerName(shop.getShopManager()); goodsShop.setPhone(shop.getPhone()); goodsShop.setAddress(shop.getAddress()); goodsShopService.save(goodsShop); //判断是否参加秒杀活动 if (addGoodsDTO.isActivity()){ //秒杀活动 SeckillActivityInfo seckillActivityInfo = new SeckillActivityInfo(); seckillActivityInfo.setDelFlag(0); seckillActivityInfo.setCreateTime(LocalDateTime.now()); seckillActivityInfo.setGoodId(goods.getId()); seckillActivityInfo.setMaxNum(addGoodsDTO.getMaxNum()); seckillActivityInfo.setStartTime(addGoodsDTO.getStartTime()); seckillActivityInfo.setEndTime(addGoodsDTO.getEndTime()); seckillActivityInfo.setIsShelves(1);//默认上架 seckillActivityInfoService.save(seckillActivityInfo); //秒杀活动价格 GoodsSeckill goodsSeckill = new GoodsSeckill(); goodsSeckill.setSellingPrice(addGoodsDTO.getActivityPrice()); goodsSeckill.setIntegral(getPoint(addGoodsDTO.getActivityPrice())); goodsSeckill.setSeckillActivityInfoId(seckillActivityInfo.getId()); goodsSeckillService.save(goodsSeckill); } } /** * 获取商品当前的价格,就是看当前商品是否在秒杀活动中 */ public Price getPrice( Integer goodsId){ //判断是否有在秒杀活动时间中 Price price = new Price(); SeckillActivityInfo one = seckillActivityInfoService.getOne(new LambdaQueryWrapper<SeckillActivityInfo>().eq(SeckillActivityInfo::getGoodId, goodsId) .eq(SeckillActivityInfo::getIsShelves, 1).eq(SeckillActivityInfo::getDelFlag, 0) .last(" and now() between start_time and end_time order by create_time desc limit 0, 1")); GoodsSeckill goodsSeckill = null;//秒杀配置 if(null != one){ //有秒杀活动,查看秒杀价格 goodsSeckill = goodsSeckillService.getOne(new LambdaQueryWrapper<GoodsSeckill>().eq(GoodsSeckill::getSeckillActivityInfoId, one.getId())); } //没有秒杀活动或者添加的普通商品则使用秒杀活动价格 if(null == goodsSeckill ){ return null; } //秒杀活动价格 price.setCash(goodsSeckill.getSellingPrice()); //计算对应积分 price.setPoint(getPoint(price.getCash())); price.setStartTime(one.getStartTime()); price.setEndTime(one.getEndTime()); price.setPurchaseLimit(one.getMaxNum()); return price; } /** * 获取现金对应积分 */ public Integer getPoint(BigDecimal cash){ if (cash == null || cash.compareTo(BigDecimal.ZERO) < 0) { throw new IllegalArgumentException("金额不能为null或负数"); } // 获取积分兑换比例配置 R<SysConfig> info = sysConfigClient.getInfo(6L); if (info == null || info.getData() == null) { throw new RuntimeException("获取积分兑换比例配置失败"); } String configValue = info.getData().getConfigValue(); if (StringUtils.isBlank(configValue)) { throw new RuntimeException("积分兑换比例配置值为空"); } try { // 使用BigDecimal处理比例,避免精度问题 BigDecimal ratio = new BigDecimal(configValue.trim()); if (ratio.compareTo(BigDecimal.ZERO) <= 0) { throw new RuntimeException("积分兑换比例必须大于0"); } // 计算积分并四舍五入取整 return cash.multiply(ratio).intValue(); } catch (NumberFormatException e) { throw new RuntimeException("积分兑换比例配置值格式错误", e); } catch (ArithmeticException e) { throw new RuntimeException("积分计算结果溢出", e); } } } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopWithdrawServiceImpl.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.other.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.other.api.domain.ShopWithdraw; import com.ruoyi.other.mapper.ShopWithdrawMapper; import com.ruoyi.other.service.ShopWithdrawService; import org.springframework.stereotype.Service; /** * <p> * 服务实现类 * </p> * * @author luodangjia * @since 2024-11-20 */ @Service public class ShopWithdrawServiceImpl extends ServiceImpl<ShopWithdrawMapper, ShopWithdraw> implements ShopWithdrawService { } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GoodsVO.java
@@ -65,6 +65,9 @@ @ApiModelProperty(value = "活动结束时间") private LocalDateTime endTime; @ApiModelProperty(value = "状态(1=下架,2=上架)") private Integer status; @ApiModelProperty(value = "门店列表") private List<Shop> shopList; ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/ShopBalanceStatementVO.java
New file @@ -0,0 +1,32 @@ package com.ruoyi.other.vo; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @Data @ApiModel("ShopBalanceStatementVO对象") public class ShopBalanceStatementVO { @ApiModelProperty(value = "变动类型(4=提现,5=订单收入,6=订单退款)") private Integer type; @ApiModelProperty(value = "变动金额") private Integer variableAmount; @ApiModelProperty(value = "变动时间") private String createTime; @ApiModelProperty(value = "历史余额") private BigDecimal historicalBalance; @ApiModelProperty(value = "变动后余额") private BigDecimal balance; @ApiModelProperty(value = "增或减标识: 1-增 2-减") private Integer flag; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/ShopBalanceVO.java
New file @@ -0,0 +1,28 @@ package com.ruoyi.other.vo; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @Data @ApiModel("门店余额统计") public class ShopBalanceVO { @ApiModelProperty(value = "可提现金额") private BigDecimal canWithdrawMoney; @ApiModelProperty(value = "已提现金额") private BigDecimal withdrawMoney; @ApiModelProperty(value = "审核中金额") private BigDecimal withdrawAuditMoney; @ApiModelProperty(value = "余额") private BigDecimal balance; @ApiModelProperty(value = "冻结余额") private BigDecimal freezeMoney; } ruoyi-service/ruoyi-other/src/main/resources/mapper/other/ShopBalanceStatementMapper.xml
@@ -37,4 +37,22 @@ <select id="selectShopBalanceStatementList" resultType="com.ruoyi.other.api.domain.ShopBalanceStatement"> <include refid="shopBalanceStatementList"/> </select> <select id="getShopBalanceStatementList" resultType="com.ruoyi.other.vo.ShopBalanceStatementVO"> select type, historical_balance as historicalBalance variable_amount as variableAmount, balance, DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') as createTime, from t_shop_balance_statement where shop_id = #{shopId} <if test="null != startTime and null != endTime"> and create_time between #{startTime} and #{endTime} </if> <if test="null != type"> and type = #{type} </if> order by createTime desc </select> </mapper> ruoyi-service/ruoyi-other/src/main/resources/mapper/other/ShopMapper.xml
@@ -78,4 +78,23 @@ and ts.id = #{shopId} </if> </select> <select id="selectListByShopId" resultType="com.ruoyi.other.vo.GoodsVO"> SELECT tg.id as goodsId, tg.`name` as goodsName, tg.purchase_limit as purchaseLimit tg.integral, tg.introduction, tg.selling_price as sellingPrice, tg.original_price as originalPrice, tg.sale_num as saleNum, tg.home_page_picture as homePagePicture, tg.sort, tg.status FROM t_goods tg where tg.del_flag = 0 and tg.id in (select goods_id from t_goods_shop where shop_id = #{shopId}) ORDER BY ifnull(tg.sort, -1) DESC </select> </mapper>