Kaynağa Gözat

分销逻辑

licailing 4 yıl önce
ebeveyn
işleme
686de141ba

+ 10 - 4
src/main/java/com/izouma/jiashanxia/domain/Package.java

@@ -72,14 +72,20 @@ public class Package extends BaseEntity {
     @ApiModelProperty(value = "是否单独分销")
     private boolean separateDistribution;
 
-    @ApiModelProperty(value = "直推奖励比例")
+    @ApiModelProperty(value = "黄金佳人直推奖励比例")
     private BigDecimal personalRatio0;
 
-    @ApiModelProperty(value = "间推奖励比例")
+    @ApiModelProperty(value = "黄金佳人间推奖励比例")
     private BigDecimal personalRatio1;
 
-    @ApiModelProperty(value = "大团长推大团长比例")
-    private BigDecimal personalRatio2;
+    @ApiModelProperty(value = "钻石佳人直推奖励比例")
+    private BigDecimal bigExpertRatio0;
+
+    @ApiModelProperty(value = "钻石佳人间推奖励比例")
+    private BigDecimal bigExpertRatio1;
+
+//    @ApiModelProperty(value = "大团长推大团长比例")
+//    private BigDecimal personalRatio2;
 
     @ApiModelProperty(value = "可获得的优惠券id")
     @Convert(converter = LongArrayConverter.class)

+ 1 - 1
src/main/java/com/izouma/jiashanxia/enums/TransactionType.java

@@ -3,7 +3,7 @@ package com.izouma.jiashanxia.enums;
 public enum TransactionType {
     WITHDRAW("提现"),
     PROMOTE("推广新会员"),
-    CHILD_PROMOTE("级推广新会员"),
+    CHILD_PROMOTE("级推广新会员"),
 //    EXPERT("团长奖励"),
     MAKER("创客奖励"),
     GENERAL("108将奖励"),

+ 3 - 0
src/main/java/com/izouma/jiashanxia/repo/UserRepo.java

@@ -42,6 +42,9 @@ public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExe
     // 身份为其他身份的下级的数量
     long countByParentAndMemberAndDelFalse(Long parent, Member member);
 
+    // 不为普通会员的下级的数量
+    long countByParentAndMemberNotAndDelFalse(Long parent, Member member);
+
     List<User> findAllByCompanyIdIsNullAndDelFalse();
 
     // 按企业id删用户

+ 142 - 18
src/main/java/com/izouma/jiashanxia/service/OrderInfoService.java

@@ -4,9 +4,12 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
-import com.izouma.jiashanxia.domain.*;
 import com.izouma.jiashanxia.domain.Package;
-import com.izouma.jiashanxia.dto.*;
+import com.izouma.jiashanxia.domain.*;
+import com.izouma.jiashanxia.dto.CreateOrder;
+import com.izouma.jiashanxia.dto.OrderInfoDTO;
+import com.izouma.jiashanxia.dto.OrderInfoVO;
+import com.izouma.jiashanxia.dto.PageQuery;
 import com.izouma.jiashanxia.enums.*;
 import com.izouma.jiashanxia.exception.BusinessException;
 import com.izouma.jiashanxia.repo.*;
@@ -21,7 +24,10 @@ import javax.persistence.criteria.Predicate;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 
@@ -214,12 +220,12 @@ public class OrderInfoService {
 //                .build());
 
         // 上级分销
-        this.distribution2(order);
+        this.distribution3(order);
         // 短信通知
-//        User user = order.getUser();
-//        if (ObjectUtil.isNotNull(user.getPhone())) {
-//            smsService.sendNotification(user.getPhone(), order.getName(), order.getOrderNumber());
-//        }
+        User user = order.getUser();
+        if (ObjectUtil.isNotNull(user.getPhone())) {
+            smsService.sendNotification(user.getPhone(), order.getName(), order.getOrderNumber());
+        }
 
 //        orderDelayService.remove(order.getId(), order.getCreatedAt());
     }
@@ -242,11 +248,6 @@ public class OrderInfoService {
             case CANCELLED:
                 return orderInfo;
         }
-//        if (OrderInfoStatus.PAID.equals(status)) {
-//            throw new BusinessException("订单已支付,无法取消");
-//        } else if (OrderInfoStatus.CANCELLED.equals(status)) {
-//            return orderInfo;
-//        }
         orderInfo.setStatus(OrderInfoStatus.CANCELLED);
         return orderInfoRepo.save(orderInfo);
     }
@@ -309,6 +310,9 @@ public class OrderInfoService {
         }
     }
 
+    /*
+    分销
+     */
     public void distribution1(Long userId, Long parent, OrderInfo orderInfo) {
         Package aPackage = packageRepo.findById(orderInfo.getPackageId()).orElseThrow(new BusinessException("无套餐"));
 
@@ -411,21 +415,141 @@ public class OrderInfoService {
                     return;
                 }
             }
-
         }
-
     }
 
     public void distribution3(OrderInfo orderInfo) {
+        // 分销
+        Package aPackage = packageRepo.findById(orderInfo.getPackageId()).orElseThrow(new BusinessException("无记录"));
+        // 售价-结算价
+        int balance;
+        if (ObjectUtil.isNotNull(orderInfo.getStockId())) {
+            Stock stock = stockRepo.findById(orderInfo.getStockId()).orElseThrow(new BusinessException("无规格"));
+            balance = stock.getPrice().compareTo(stock.getSettlementPrice());
+        } else {
+            balance = aPackage.getAmount().compareTo(aPackage.getSettlementPrice());
+        }
+        if (balance <= 0) {
+            return;
+        }
+        BigDecimal balanceAmount = BigDecimal.valueOf(balance);
+
         Long userId = orderInfo.getUserId();
         User user = userRepo.findById(userId).orElseThrow(new BusinessException("无用户"));
-        // 不是普通用户
-        if (!Member.NORMAL.equals(user.getMember())) {
-            // 拿一级
+        User one = user;
+        User two;
+        // 普通用户
+        if (Member.NORMAL.equals(user.getMember())) {
+            one = this.getParent(user);
+            if (ObjectUtil.isNull(one)) {
+                return;
+            }
+        }
+        this.getDistribution(orderInfo, one, 1, balanceAmount, aPackage);
+        two = this.getParent(one);
+        if (ObjectUtil.isNotNull(two)) {
+            this.getDistribution(orderInfo, two, 2, balanceAmount, aPackage);
         }
 
     }
 
+    // 获得上级
+    private User getParent(User user) {
+        // 查找上级
+        if (ObjectUtil.isNotNull(user.getParent())) {
+            User parent = userRepo.findById(user.getParent()).orElseThrow(new BusinessException("无用户"));
+            if (!Member.NORMAL.equals(parent.getMember())) {
+                return parent;
+            }
+        }
+        return null;
+    }
+
+    // 用户得到的分销
+    private void getDistribution(OrderInfo orderInfo, User user, int level, BigDecimal balance, Package aPackage) {
+        BigDecimal amount;
+
+        boolean separateDis = aPackage.isSeparateDistribution();
+        // 个人佣金流水
+        CommissionRecord commission = CommissionRecord.builder()
+                .userId(user.getId())
+                .payMethod(PayMethod.YUE)
+                .fromUserId(orderInfo.getUserId())
+                .transactionType(TransactionType.PROMOTE)
+                .transactionId(orderInfo.getTransactionId())
+                .build();
+
+        switch (user.getMember()) {
+            case EXPERT:
+                if (level == 1) {
+                    if (separateDis && ObjectUtil.isNotEmpty(aPackage.getPersonalRatio0())) {
+                        amount = balance.multiply(aPackage.getPersonalRatio0());
+                    } else {
+                        BigDecimal personalRatio0 = sysConfigService.getBigDecimal("PERSONAL_RATIO_0");
+                        amount = balance.multiply(personalRatio0);
+                    }
+                    if (BigDecimal.ZERO.compareTo(amount) <= 0) {
+                        return;
+                    }
+                    // 加用户余额
+                    user.setAmount(user.getAmount().add(amount));
+                    // 直推类型
+                    commission.setTransactionType(TransactionType.PROMOTE);
+                } else {
+                    if (separateDis && ObjectUtil.isNotEmpty(aPackage.getPersonalRatio1())) {
+                        amount = balance.multiply(aPackage.getPersonalRatio1());
+                    } else {
+                        BigDecimal personalRatio1 = sysConfigService.getBigDecimal("PERSONAL_RATIO_1");
+                        amount = balance.multiply(personalRatio1);
+                    }
+                    if (BigDecimal.ZERO.compareTo(amount) <= 0) {
+                        return;
+                    }
+                    // 二级收益暂存
+                    user.setCacheAmount(user.getCacheAmount().add(amount));
+                    // 间推类型
+                    commission.setTransactionType(TransactionType.CHILD_PROMOTE);
+                }
+                userRepo.save(user);
+                commission.setAmount(amount);
+                commissionRecordRepo.save(commission);
+                break;
+            case BIG_EXPERT:
+                if (level == 1) {
+                    if (separateDis && ObjectUtil.isNotEmpty(aPackage.getBigExpertRatio0())) {
+                        amount = balance.multiply(aPackage.getBigExpertRatio0());
+                    } else {
+                        BigDecimal personalRatio0 = sysConfigService.getBigDecimal("BIG_EXPERT_RATIO_0");
+                        amount = balance.multiply(personalRatio0);
+                    }
+                    if (BigDecimal.ZERO.compareTo(amount) <= 0) {
+                        return;
+                    }
+                    // 直推类型
+                    commission.setTransactionType(TransactionType.PROMOTE);
+                } else {
+                    if (separateDis && ObjectUtil.isNotEmpty(aPackage.getBigExpertRatio1())) {
+                        amount = balance.multiply(aPackage.getBigExpertRatio1());
+                    } else {
+                        BigDecimal personalRatio1 = sysConfigService.getBigDecimal("BIG_EXPERT_RATIO_1");
+                        amount = balance.multiply(personalRatio1);
+                    }
+                    if (BigDecimal.ZERO.compareTo(amount) <= 0) {
+                        return;
+                    }
+                    // 间推类型
+                    commission.setTransactionType(TransactionType.CHILD_PROMOTE);
+                }
+                user.setAmount(user.getAmount().add(amount));
+                userRepo.save(user);
+                commission.setAmount(amount);
+                commissionRecordRepo.save(commission);
+                break;
+            default:
+                break;
+        }
+    }
+
     /*
     间推
      */

+ 31 - 7
src/main/java/com/izouma/jiashanxia/service/UserService.java

@@ -146,7 +146,7 @@ public class UserService {
                     if (ObjectUtil.isNull(userInfo.getParent())) {
                         User parentUser = userRepo.findById(parent).orElseThrow(new BusinessException("无上级"));
                         // 上级不是普通会员
-                        if (!Member.NORMAL.equals(parentUser.getMember())){
+                        if (!Member.NORMAL.equals(parentUser.getMember())) {
                             userInfo.setParent(parent);
                         }
                     }
@@ -523,21 +523,45 @@ public class UserService {
     身份升级
      */
     public void upgrade(Long parent) {
-        long num = userRepo.countByParentAndMemberAndDelFalse(parent,Member.EXPERT);
-        // 成为钻石合伙人
+        User user = userRepo.findById(parent).orElseThrow(new BusinessException("无上级"));
+        Member member = user.getMember();
+        // 普通用户不可升级
+        if (Member.NORMAL.equals(member)) {
+            return;
+        }
+        // 已到最高级
+        if (Member.PARTNER.equals(member)){
+            return;
+        }
+
+        // 钻石佳人数量
+        long bigExpertNum = userRepo.countByParentAndMemberAndDelFalse(parent, Member.BIG_EXPERT);
+        // 成为钻石合伙人需要的钻石佳人数量
+        int upgradePartnerByBig = sysConfigService.getInt("UPGRADE_PARTNER_BY_BIG");
+        if (bigExpertNum >= upgradePartnerByBig) {
+            user.setMember(Member.PARTNER);
+            userRepo.save(user);
+            return;
+        }
+        // 下级不为普通会员的数量
+        long num = userRepo.countByParentAndMemberNotAndDelFalse(parent, Member.NORMAL);
+        // 成为钻石合伙人需要的黄金佳人数量
         int upgradePartner = sysConfigService.getInt("UPGRADE_PARTNER");
         if (num > upgradePartner) {
-            User user = userRepo.findById(parent).orElseThrow(new BusinessException("无上级"));
             user.setMember(Member.PARTNER);
             userRepo.save(user);
             return;
         }
-
-        // 成为钻石佳人
+        // 成为钻石佳人需要的黄金佳人数量
+        if (Member.BIG_EXPERT.equals(member)) {
+            return;
+        }
         int upgradeBigExpert = sysConfigService.getInt("UPGRADE_BIG_EXPERT");
         if (num > upgradeBigExpert) {
-            User user = userRepo.findById(parent).orElseThrow(new BusinessException("无上级"));
             user.setMember(Member.BIG_EXPERT);
+            // 释放暂存金额
+            user.setAmount(user.getAmount().add(user.getCacheAmount()));
+            user.setCacheAmount(BigDecimal.ZERO);
             userRepo.save(user);
         }
     }

+ 89 - 85
src/main/vue/src/components/PackageEdit.vue

@@ -182,56 +182,60 @@
                     <el-radio :label="false">系统分销</el-radio>
                 </el-radio-group>
             </el-form-item>
-            <el-form-item prop="personalRatio0" label="直推比例" v-if="formData.separateDistribution">
-                <el-input-number
-                    type="number"
-                    v-model="formData.personalRatio0"
-                    class="select-width"
-                    :max="1"
-                    :min="0"
-                    :step="0.01"
-                ></el-input-number>
-            </el-form-item>
-            <el-form-item prop="personalRatio1" label="二级比例" v-if="formData.separateDistribution">
-                <el-input-number
-                    type="number"
-                    v-model="formData.personalRatio1"
-                    class="select-width"
-                    :max="1"
-                    :min="0"
-                    :step="0.01"
-                ></el-input-number>
-            </el-form-item>
-            <el-form-item prop="personalRatio2" label="三级比例" v-if="formData.separateDistribution">
-                <el-input-number
-                    type="number"
-                    v-model="formData.personalRatio2"
-                    class="select-width"
-                    :max="1"
-                    :min="0"
-                    :step="0.01"
-                ></el-input-number>
-            </el-form-item>
-            <!-- <el-form-item prop="makerRatio" label="创客比例" v-if="formData.separateDistribution">
-                <el-input-number
-                    type="number"
-                    v-model="formData.makerRatio"
-                    class="select-width"
-                    :max="1"
-                    :min="0"
-                    :step="0.01"
-                ></el-input-number>
+            <el-form-item label="自主分销" v-if="formData.separateDistribution">
+                <div class="distribution">
+                    <el-row>
+                        <p>黄金佳人:</p>
+                        <el-col :span="11">
+                            <span>直推比例</span>
+                            <el-input-number
+                                type="number"
+                                v-model="formData.personalRatio0"
+                                class="input"
+                                :max="1"
+                                :min="0"
+                                :step="0.01"
+                            ></el-input-number>
+                        </el-col>
+                        <el-col :span="11">
+                            <span>间推比例</span>
+                            <el-input-number
+                                type="number"
+                                v-model="formData.personalRatio1"
+                                class="input"
+                                :max="1"
+                                :min="0"
+                                :step="0.01"
+                            ></el-input-number>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <p>钻石佳人:</p>
+                        <el-col :span="11">
+                            <span>直推比例</span>
+                            <el-input-number
+                                type="number"
+                                v-model="formData.bigExpertRatio0"
+                                class="input"
+                                :max="1"
+                                :min="0"
+                                :step="0.01"
+                            ></el-input-number>
+                        </el-col>
+                        <el-col :span="11">
+                            <span>间推比例</span>
+                            <el-input-number
+                                type="number"
+                                v-model="formData.bigExpertRatio1"
+                                class="input"
+                                :max="1"
+                                :min="0"
+                                :step="0.01"
+                            ></el-input-number>
+                        </el-col>
+                    </el-row>
+                </div>
             </el-form-item>
-            <el-form-item prop="generalRatio" label="108将比例" v-if="formData.separateDistribution">
-                <el-input-number
-                    type="number"
-                    v-model="formData.generalRatio"
-                    class="select-width"
-                    :min="0"
-                    :max="1"
-                    :step="0.01"
-                ></el-input-number>
-            </el-form-item> -->
             <el-form-item label="核销赠送优惠券" prop="couponId">
                 <el-select multiple v-model="formData.couponId" class="select-width">
                     <el-option v-for="item in coupons" :key="item.id" :label="item.name" :value="item.id">
@@ -442,13 +446,27 @@ export default {
                         trigger: 'blur'
                     }
                 ],
-                // amount: [
-                //     {
-                //         required: true,
-                //         message: '请输入金额',
-                //         trigger: 'blur'
-                //     }
-                // ],
+                amount: [
+                    {
+                        required: true,
+                        message: '请输入金额',
+                        trigger: 'blur'
+                    }
+                ],
+                originalPrice: [
+                    {
+                        required: true,
+                        message: '请输入金额',
+                        trigger: 'blur'
+                    }
+                ],
+                settlementPrice: [
+                    {
+                        required: true,
+                        message: '请输入金额',
+                        trigger: 'blur'
+                    }
+                ],
                 categoryId: [
                     {
                         required: true,
@@ -650,7 +668,7 @@ export default {
 .spec {
     margin-top: 15px;
     background-color: #f7f7f7;
-    padding: 20px 20px 15px 20px;
+    padding: 15px 20px 15px 20px;
     span {
         font-size: 13px;
         color: #565b66;
@@ -673,38 +691,24 @@ export default {
         }
     }
 }
-.stock {
-    display: flex;
-    align-items: center;
-    margin-top: 20px;
-    .name {
-        width: 200px;
-    }
-    .name2 {
-        width: 180px;
-    }
-
-    .value {
-        width: 180px;
-    }
-
+.distribution {
+    background-color: #f7f7f7;
+    padding: 15px 20px 15px 20px;
     span {
-        font-size: 12px;
+        font-size: 13px;
         color: #565b66;
         line-height: 16px;
-        padding: 0 20px 0 20px;
+        padding: 0 15px 0 15px;
     }
-
-    .el-button {
-        height: 36px;
-        border-width: 0;
-
-        &.del {
-            width: 36px;
-            padding: 9px 5px;
-            font-size: 16px;
-            margin-left: 10px;
-        }
+    p {
+        font-size: 13px;
+        color: #565b66;
+        line-height: 15px;
+        padding: 0 15px 0 15px;
+    }
+    .input {
+        width: 180px;
+        margin: 0 10px 5px 0;
     }
 }
 .subform {