xiongzhu 4 anni fa
parent
commit
8be46d1df3

+ 32 - 0
src/main/java/com/izouma/nineth/converter/DropTargetConverter.java

@@ -0,0 +1,32 @@
+package com.izouma.nineth.converter;
+
+import com.alibaba.fastjson.JSON;
+import com.izouma.nineth.domain.DropTarget;
+import com.izouma.nineth.domain.FileObject;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+import java.util.List;
+
+@Converter
+public class DropTargetConverter implements AttributeConverter<List<DropTarget>, String> {
+    @Override
+    public String convertToDatabaseColumn(List<DropTarget> dropTargets) {
+        if (dropTargets != null) {
+            return JSON.toJSONString(dropTargets);
+        }
+        return null;
+    }
+
+    @Override
+    public List<DropTarget> convertToEntityAttribute(String s) {
+        if (StringUtils.isNotEmpty(s)) {
+            try {
+                return JSON.parseArray(s, DropTarget.class);
+            } catch (Exception ignored) {
+            }
+        }
+        return null;
+    }
+}

+ 10 - 0
src/main/java/com/izouma/nineth/domain/AirDrop.java

@@ -1,5 +1,6 @@
 package com.izouma.nineth.domain;
 
+import com.izouma.nineth.converter.DropTargetConverter;
 import com.izouma.nineth.converter.LongArrayConverter;
 import com.izouma.nineth.converter.StringArrayConverter;
 import com.izouma.nineth.enums.AirDropType;
@@ -47,6 +48,15 @@ public class AirDrop extends BaseEntity {
     @ApiModelProperty("用户ID")
     private List<Long> userIds;
 
+    @Column(columnDefinition = "TEXT")
+    @Convert(converter = DropTargetConverter.class)
+    private List<DropTarget> targets;
+
+    @Column(columnDefinition = "TEXT")
+    @Convert(converter = LongArrayConverter.class)
+    @ApiModelProperty("数量")
+    private List<Long> num;
+
     @Column(columnDefinition = "TEXT")
     private String result;
 

+ 14 - 0
src/main/java/com/izouma/nineth/domain/DropTarget.java

@@ -0,0 +1,14 @@
+package com.izouma.nineth.domain;
+
+import lombok.Data;
+
+@Data
+public class DropTarget {
+    private Long userId;
+
+    private String phone;
+
+    private String nickname;
+
+    private int num;
+}

+ 56 - 36
src/main/java/com/izouma/nineth/service/AirDropService.java

@@ -18,6 +18,7 @@ import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 @AllArgsConstructor
@@ -41,6 +42,9 @@ public class AirDropService {
     }
 
     public AirDrop create(AirDrop record) {
+        if (record.getTargets().isEmpty()) throw new BusinessException("空投对象不能为空");
+        if (record.getTargets().stream().mapToInt(DropTarget::getNum).sum() > 300)
+            throw new BusinessException("空投数量不能超过300");
         if (AirDropType.coupon == record.getType()) {
             Coupon coupon = couponRepo.findById(record.getCouponId()).orElseThrow(new BusinessException("兑换券不存在"));
             record.getUserIds().stream().parallel().forEach(userId -> {
@@ -60,51 +64,67 @@ public class AirDropService {
             if (!record.isIgnoreStockCheck() && collection.getStock() < record.getUserIds().size()) {
                 throw new BusinessException("藏品库存不足");
             }
-            List<User> users = userRepo.findByIdInAndDelFalse(record.getUserIds());
-            for (User user : users) {
+
+            List<User> users = userRepo.findByIdInAndDelFalse(record.getTargets().stream()
+                    .map(DropTarget::getUserId).collect(Collectors.toList()));
+
+            for (DropTarget target : record.getTargets()) {
+                User user = users.stream().filter(u -> u.getId().equals(target.getUserId()))
+                        .findFirst().orElse(null);
+                if (user == null) continue;
                 try {
-                    if (collection.getType() == CollectionType.BLIND_BOX) {
-                        BlindBoxItem winItem = collectionService.draw(collection.getId());
-                        if (record.isSimulateOrder()) {
-                            assetService.createAsset(winItem, user, 0L, collection.getPrice(), "出售",
-                                    winItem.getTotal() > 1 ? collectionService.getNextNumber(winItem.getCollectionId()) : null,
-                                    collection.getHoldDays());
-                        } else {
-                            //查看有无vip权限
-                            CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo.findByCollectionId(record.getCollectionId());
-                            if (ObjectUtils.isNotEmpty(collectionPrivilege)) {
-                                if (collectionPrivilege.isVip()) {
-                                    //更新vip信息
-                                    userRepo.updateVipPurchase(user.getId(), 1);
+                    for (int i = 0; i < target.getNum(); i++) {
+                        if (collection.getType() == CollectionType.BLIND_BOX) {
+                            BlindBoxItem winItem = collectionService.draw(collection.getId());
+                            if (record.isSimulateOrder()) {
+                                assetService.createAsset(winItem, user, 0L, collection.getPrice(), "出售",
+                                        winItem.getTotal() > 1 ?
+                                                collectionService.getNextNumber(winItem.getCollectionId()) : null,
+                                        collection.getHoldDays());
+                            } else {
+                                //查看有无vip权限
+                                CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo
+                                        .findByCollectionId(record.getCollectionId());
+                                if (ObjectUtils.isNotEmpty(collectionPrivilege)) {
+                                    if (collectionPrivilege.isVip()) {
+                                        //更新vip信息
+                                        userRepo.updateVipPurchase(user.getId(), 1);
+                                    }
                                 }
+                                assetService.createAsset(winItem, user, null, null, "空投",
+                                        winItem.getTotal() > 1 ?
+                                                collectionService.getNextNumber(winItem.getCollectionId()) : null,
+                                        collection.getHoldDays());
                             }
-                            assetService.createAsset(winItem, user, null, null, "空投",
-                                    collectionService.getNextNumber(winItem.getCollectionId()), collection.getHoldDays());
-                        }
-                    } else {
-                        if (record.isSimulateOrder()) {
-                            assetService.createAsset(collection, user, 0L, collection.getPrice(), "出售",
-                                    collection.getTotal() > 1 ? collectionService.getNextNumber(collection.getId()) : null);
                         } else {
-                            //查看有无vip权限
-                            CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo.findByCollectionId(record.getCollectionId());
-                            if (ObjectUtils.isNotEmpty(collectionPrivilege)) {
-                                if (collectionPrivilege.isVip()) {
-                                    //更新vip信息
-                                    userRepo.updateVipPurchase(user.getId(), 1);
+                            if (record.isSimulateOrder()) {
+                                assetService.createAsset(collection, user, 0L, collection.getPrice(),
+                                        "出售", collection.getTotal() > 1 ?
+                                                collectionService.getNextNumber(collection.getId()) : null);
+                            } else {
+                                //查看有无vip权限
+                                CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo
+                                        .findByCollectionId(record.getCollectionId());
+                                if (ObjectUtils.isNotEmpty(collectionPrivilege)) {
+                                    if (collectionPrivilege.isVip()) {
+                                        //更新vip信息
+                                        userRepo.updateVipPurchase(user.getId(), 1);
+                                    }
+                                }
+                                Asset asset = assetService.createAsset(collection, user, null, null,
+                                        "空投", collection.getTotal() > 1 ?
+                                                collectionService.getNextNumber(collection.getId()) : null);
+                                //创建展厅
+                                if (collection.getType() == CollectionType.SHOWROOM) {
+                                    showroomService.save(asset);
                                 }
                             }
-                            Asset asset = assetService.createAsset(collection, user, null, null, "空投", collectionService.getNextNumber(collection.getId()));
-                            //创建展厅
-                            if (collection.getType() == CollectionType.SHOWROOM) {
-                                showroomService.save(asset);
-                            }
-                        }
 //                        Asset asset = assetService.createAsset(collection, user, null, null, "空投", collectionService.getNextNumber(collection.getId()));
 
+                        }
+                        collectionService.decreaseStock(collection.getId(), 1);
+                        collectionService.increaseSale(collection.getId(), 1);
                     }
-                    collectionService.decreaseStock(collection.getId(), 1);
-                    collectionService.increaseSale(collection.getId(), 1);
                 } catch (Exception e) {
                     log.error("空投出错", e);
                 }

+ 33 - 7
src/main/vue/src/views/AirDropEdit.vue

@@ -44,11 +44,22 @@
                     <el-form-item prop="collectionId" label="藏品" v-else>
                         <collection-search v-model="formData.collectionId"></collection-search>
                     </el-form-item>
-                    <el-form-item prop="userIds" label="空投对象">
-                        <el-table :data="users">
+                    <el-form-item prop="targets" label="空投对象" style="width: 800px">
+                        <el-table :data="formData.targets" style="width: 600px">
                             <el-table-column type="index" label="#" width="50"></el-table-column>
                             <el-table-column label="手机" prop="phone"></el-table-column>
                             <el-table-column label="昵称" prop="nickname"></el-table-column>
+                            <el-table-column label="数量" prop="num">
+                                <template v-slot="{ row }">
+                                    <el-input-number
+                                        v-model="row.num"
+                                        :min="1"
+                                        :max="300"
+                                        :step="1"
+                                        size="mini"
+                                    ></el-input-number>
+                                </template>
+                            </el-table-column>
                             <el-table-column width="80" align="center">
                                 <template v-slot="{ row, $index }">
                                     <el-button type="text" @click="delUser($index)">删除</el-button>
@@ -130,7 +141,8 @@ export default {
                 couponLimited: false,
                 simulateOrder: false,
                 ignoreStockCheck: false,
-                userIds: []
+                userIds: [],
+                targets: []
             },
             rules: {
                 name: [
@@ -147,7 +159,7 @@ export default {
                         trigger: 'blur'
                     }
                 ],
-                userIds: [
+                targets: [
                     {
                         validator: (rule, value, callback) => {
                             if (value && value.length > 0) {
@@ -182,7 +194,6 @@ export default {
             phone: '',
             showPhoneDialog: false,
             searchingPhone: false,
-            users: [],
             coupons: [],
             advanceMode: false
         };
@@ -252,7 +263,22 @@ export default {
                         .then(res => {
                             this.showPhoneDialog = false;
                             this.searchingPhone = false;
-                            this.users = this.users.concat(res.users.filter(i => !this.users.find(e => e.id === i.id)));
+                            this.$set(
+                                this.formData,
+                                'targets',
+                                this.formData.targets.concat(
+                                    res.users
+                                        .filter(i => !this.formData.targets.find(e => e.userId === i.id))
+                                        .map(i => {
+                                            return {
+                                                userId: i.id,
+                                                phone: i.phone,
+                                                nickname: i.nickname,
+                                                num: 1
+                                            };
+                                        })
+                                )
+                            );
                             if (res.notFound && res.notFound.length) {
                                 this.$alert('未找到以下手机对应的用户:<br>' + res.notFound.join('、'), '', {
                                     dangerouslyUseHTMLString: true
@@ -269,7 +295,7 @@ export default {
                 });
         },
         delUser(index) {
-            this.users.splice(index, 1);
+            this.formData.targets.splice(index, 1);
         }
     },
     watch: {

+ 71 - 18
src/test/java/com/izouma/nineth/service/OrderServiceTest.java

@@ -1,5 +1,6 @@
 package com.izouma.nineth.service;
 
+import com.alibaba.fastjson.JSONObject;
 import com.alipay.api.domain.OrderInfoDTO;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.huifu.adapay.core.exception.BaseAdaPayException;
@@ -9,10 +10,8 @@ import com.izouma.nineth.TokenHistory;
 import com.izouma.nineth.domain.Collection;
 import com.izouma.nineth.domain.*;
 import com.izouma.nineth.dto.UserBankCard;
-import com.izouma.nineth.enums.AssetStatus;
-import com.izouma.nineth.enums.AuthStatus;
-import com.izouma.nineth.enums.OrderStatus;
-import com.izouma.nineth.enums.TransferReason;
+import com.izouma.nineth.enums.*;
+import com.izouma.nineth.event.OrderNotifyEvent;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
 import com.izouma.nineth.utils.DateTimeUtils;
@@ -21,6 +20,7 @@ import com.izouma.nineth.utils.SnowflakeIdWorker;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.security.SecurityProperties;
@@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.security.SecurityProperties;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -58,6 +59,12 @@ public class OrderServiceTest extends ApplicationTests {
     private BlindBoxItemRepo  blindBoxItemRepo;
     @Autowired
     private SnowflakeIdWorker snowflakeIdWorker;
+    @Autowired
+    private ErrorOrderRepo    errorOrderRepo;
+    @Autowired
+    private RocketMQTemplate  rocketMQTemplate;
+    @Autowired
+    private SandPayService    sandPayService;
 
     @Test
     public void create() {
@@ -195,21 +202,21 @@ public class OrderServiceTest extends ApplicationTests {
         orderRepo.findByCollectionId(8012L).stream()
                 .filter(o -> o.getStatus() == OrderStatus.FINISH || o.getStatus() == OrderStatus.PROCESSING)
                 .parallel().forEach(order -> {
-            List<Asset> assets = assetRepo.findByOrderId(order.getId());
-            if (assets.size() > 1) {
-                assets.sort(Comparator.comparing(Asset::getCreatedAt));
-                for (int i = 1; i < assets.size(); i++) {
-                    assetRepo.delete(assets.get(i));
-                    tokenHistoryRepo.deleteByTokenId(assets.get(i).getTokenId());
-                    if (assets.get(i).getPublicCollectionId() != null) {
-                        collectionRepo.findById(assets.get(i).getPublicCollectionId()).ifPresent(c -> {
-                            collectionRepo.delete(c);
-                        });
+                    List<Asset> assets = assetRepo.findByOrderId(order.getId());
+                    if (assets.size() > 1) {
+                        assets.sort(Comparator.comparing(Asset::getCreatedAt));
+                        for (int i = 1; i < assets.size(); i++) {
+                            assetRepo.delete(assets.get(i));
+                            tokenHistoryRepo.deleteByTokenId(assets.get(i).getTokenId());
+                            if (assets.get(i).getPublicCollectionId() != null) {
+                                collectionRepo.findById(assets.get(i).getPublicCollectionId()).ifPresent(c -> {
+                                    collectionRepo.delete(c);
+                                });
+                            }
+                        }
+                        ids.add(order.getId());
                     }
-                }
-                ids.add(order.getId());
-            }
-        });
+                });
         System.out.println(ids);
     }
 
@@ -276,4 +283,50 @@ public class OrderServiceTest extends ApplicationTests {
             assetService.transfer(asset, order.getPrice(), user, TransferReason.TRANSFER, order.getId());
         }
     }
+
+    @Test
+    public void fixCancel() {
+        errorOrderRepo.findAll().stream().filter(o ->
+                        "状态错误 CANCELLED".equals(o.getErrorMessage()) &&
+                                o.getCreatedAt().isAfter(LocalDate.of(2022, 05, 13).atStartOfDay()))
+                .forEach(errorOrder -> {
+                    Order order = orderRepo.findById(errorOrder.getOrderId()).orElseThrow(new BusinessException("订单"));
+                    Asset asset = assetRepo.findById(order.getAssetId()).orElseThrow(new BusinessException("无"));
+                    Collection collection = collectionRepo.findById(order.getCollectionId()).orElse(null);
+                    if (AssetStatus.NORMAL == asset.getStatus()
+                            && OrderStatus.CANCELLED == order.getStatus()
+                            && collection != null) {
+                        order.setStatus(OrderStatus.NOT_PAID);
+                        order.setCreatedAt(LocalDateTime.now());
+                        orderRepo.save(order);
+                        rocketMQTemplate.syncSend("order-notify-topic",
+                                new OrderNotifyEvent(errorOrder.getOrderId(), PayMethod.ALIPAY, errorOrder.getTransactionId(), System.currentTimeMillis()));
+                    } else if (order.getStatus() == OrderStatus.FINISH) {
+                        errorOrderRepo.delete(errorOrder);
+                    } else {
+                        JSONObject res = sandPayService.refund(order.getId() + "", order.getTotalPrice());
+                        if ("000000".equals(res.getJSONObject("head").getString("respCode"))) {
+                            errorOrderRepo.delete(errorOrder);
+                        }
+                    }
+                });
+    }
+
+    @Test
+    public void refunddd() {
+        errorOrderRepo.findAll().stream().filter(o ->
+                        "gift".equals(o.getType()) &&
+                                o.getCreatedAt().isAfter(LocalDate.of(2022, 05, 13).atStartOfDay()))
+                .forEach(errorOrder -> {
+                    System.out.println(errorOrder.getOrderId());
+                    String orderId = errorOrder.getOrderId() + "";
+                    for (int i = orderId.length(); i < 12; i++) {
+                        orderId = "0" + orderId;
+                    }
+                    JSONObject res = sandPayService.refund(orderId, new BigDecimal("1"));
+                    if ("000000".equals(res.getJSONObject("head").getString("respCode"))) {
+                        errorOrderRepo.delete(errorOrder);
+                    }
+                });
+    }
 }