Browse Source

Merge branch 'dev' of xiongzhu/raex_back into master

wangqifan 3 years ago
parent
commit
256823056b

+ 1 - 1
src/main/java/com/izouma/nineth/domain/Company.java

@@ -32,5 +32,5 @@ public class Company extends BaseEntity {
 
 
     private boolean airdrop;
     private boolean airdrop;
 
 
-
+    private boolean meta;
 }
 }

+ 7 - 0
src/main/java/com/izouma/nineth/repo/BalanceRecordRepo.java

@@ -32,6 +32,13 @@ public interface BalanceRecordRepo extends JpaRepository<BalanceRecord, Long>, J
     @Query("select sum(b.amount) from BalanceRecord b where b.type = 'RECHARGE' and b.del = false and b.time <?2 and b.time >?1")
     @Query("select sum(b.amount) from BalanceRecord b where b.type = 'RECHARGE' and b.del = false and b.time <?2 and b.time >?1")
     BigDecimal sumRechargeToday(LocalDateTime start, LocalDateTime end);
     BigDecimal sumRechargeToday(LocalDateTime start, LocalDateTime end);
 
 
+    @Query("select sum(b.amount) from BalanceRecord b where b.type = 'WITHDRAW' and b.del = false and b.time <?2 and b.time >?1")
+    BigDecimal sumWithdrawToday(LocalDateTime start, LocalDateTime end);
+
     @Query("select sum(b.amount) from BalanceRecord b where b.type = 'RECHARGE' and b.del = false and b.time <?2 and b.time >?1 and b.userId = ?3")
     @Query("select sum(b.amount) from BalanceRecord b where b.type = 'RECHARGE' and b.del = false and b.time <?2 and b.time >?1 and b.userId = ?3")
     BigDecimal sumRechargeUser(LocalDateTime start, LocalDateTime end, Long userId);
     BigDecimal sumRechargeUser(LocalDateTime start, LocalDateTime end, Long userId);
+
+    List<BalanceRecord> findByDel(boolean del);
+
+    List<BalanceRecord> findByTypeAndCreatedAtBetweenAndAmountGreaterThan(BalanceType type, LocalDateTime start, LocalDateTime end, BigDecimal amount);
 }
 }

+ 4 - 0
src/main/java/com/izouma/nineth/repo/DomainOrderRepo.java

@@ -12,6 +12,7 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.jpa.repository.Query;
 
 
 import javax.transaction.Transactional;
 import javax.transaction.Transactional;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
 
 
@@ -33,4 +34,7 @@ public interface DomainOrderRepo extends JpaRepository<DomainOrder, Long>, JpaSp
     Page<DomainOrder> searchUsedDomain(String name, OrderStatus status, Pageable pageable);
     Page<DomainOrder> searchUsedDomain(String name, OrderStatus status, Pageable pageable);
 
 
     List<DomainOrder> findByOrderStatusAndCreatedAtBeforeAndDelFalse(OrderStatus orderStatus, LocalDateTime createdAt);
     List<DomainOrder> findByOrderStatusAndCreatedAtBeforeAndDelFalse(OrderStatus orderStatus, LocalDateTime createdAt);
+
+    @Query("select sum(price) from DomainOrder where createdAt <= ?2 and createdAt >= ?1 and orderStatus = 'FINISH'")
+    BigDecimal sumToday(LocalDateTime start, LocalDateTime end);
 }
 }

+ 3 - 0
src/main/java/com/izouma/nineth/repo/OrderRepo.java

@@ -118,4 +118,7 @@ public interface OrderRepo extends JpaRepository<Order, Long>, JpaSpecificationE
             " SELECT a.id id, o.name name,a.prefix_name prefixName, o.source source,COUNT(*) num FROM order_info o LEFT JOIN collection_info a ON o.collection_id = a.id WHERE o.`status` = 'FINISH' and o.source = 'OFFICIAL' AND o.pay_time > ?1 GROUP BY a.prefix_name) a " +
             " SELECT a.id id, o.name name,a.prefix_name prefixName, o.source source,COUNT(*) num FROM order_info o LEFT JOIN collection_info a ON o.collection_id = a.id WHERE o.`status` = 'FINISH' and o.source = 'OFFICIAL' AND o.pay_time > ?1 GROUP BY a.prefix_name) a " +
             "GROUP BY a.prefixName ORDER BY (SUM(a.num)) DESC LIMIT 10", nativeQuery = true)
             "GROUP BY a.prefixName ORDER BY (SUM(a.num)) DESC LIMIT 10", nativeQuery = true)
     List<Map<String, String>> transactionTopTen(LocalDateTime payTime);
     List<Map<String, String>> transactionTopTen(LocalDateTime payTime);
+
+    @Query("select sum(totalPrice) from Order  where status = 'FINISH' and createdAt <= ?2 and createdAt >= ?1 and companyId <> 1")
+    BigDecimal sumSaas(LocalDateTime start, LocalDateTime end);
 }
 }

+ 6 - 0
src/main/java/com/izouma/nineth/repo/PhotoAssetRepo.java

@@ -9,6 +9,7 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.jpa.repository.Query;
 
 
 import javax.transaction.Transactional;
 import javax.transaction.Transactional;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
 
 
@@ -25,4 +26,9 @@ public interface PhotoAssetRepo extends JpaRepository<PhotoAsset, Long>, JpaSpec
     List<PhotoAsset> findByOrderStatusAndCreatedAtBeforeAndDelFalse(OrderStatus orderStatus, LocalDateTime localDateTime);
     List<PhotoAsset> findByOrderStatusAndCreatedAtBeforeAndDelFalse(OrderStatus orderStatus, LocalDateTime localDateTime);
 
 
     PhotoAsset findFirstByCreateAssetId(Long id);
     PhotoAsset findFirstByCreateAssetId(Long id);
+
+    List<PhotoAsset> findAllByCreatedAtBetweenAndStatus(LocalDateTime start, LocalDateTime end, CollectionStatus status);
+
+    @Query("select sum(t.price) from PhotoAsset t where t.orderStatus = 'FINISH' and t.createdAt <= ?2 and t.createdAt >= ?1 and t.destroyed = false ")
+    BigDecimal sumPaid(LocalDateTime start, LocalDateTime end);
 }
 }

+ 54 - 39
src/main/java/com/izouma/nineth/service/AssetService.java

@@ -55,28 +55,28 @@ import java.util.stream.Collectors;
 @Slf4j
 @Slf4j
 public class AssetService {
 public class AssetService {
 
 
-    private AssetRepo assetRepo;
-    private UserRepo userRepo;
-    private CollectionRepo collectionRepo;
-    private OrderRepo orderRepo;
-    private TokenHistoryRepo tokenHistoryRepo;
-    private SysConfigService sysConfigService;
-    private RocketMQTemplate rocketMQTemplate;
-    private GeneralProperties generalProperties;
-    private ShowroomRepo showroomRepo;
-    private ShowCollectionRepo showCollectionRepo;
+    private AssetRepo               assetRepo;
+    private UserRepo                userRepo;
+    private CollectionRepo          collectionRepo;
+    private OrderRepo               orderRepo;
+    private TokenHistoryRepo        tokenHistoryRepo;
+    private SysConfigService        sysConfigService;
+    private RocketMQTemplate        rocketMQTemplate;
+    private GeneralProperties       generalProperties;
+    private ShowroomRepo            showroomRepo;
+    private ShowCollectionRepo      showCollectionRepo;
     private CollectionPrivilegeRepo collectionPrivilegeRepo;
     private CollectionPrivilegeRepo collectionPrivilegeRepo;
-    private PasswordEncoder passwordEncoder;
-    private MintActivityRepo mintActivityRepo;
-    private DestroyRecordRepo destroyRecordRepo;
-    private AirDropService airDropService;
-    private HCChainService hcChainService;
-    private RockRecordService rockRecordService;
-    private RockRecordRepo rockRecordRepo;
-    private AssetLockRepo assetLockRepo;
-    private UserBalanceService userBalanceService;
-    private PhotoAssetRepo photoAssetRepo;
-    private NumberSeqRepo numberSeqRepo;
+    private PasswordEncoder         passwordEncoder;
+    private MintActivityRepo        mintActivityRepo;
+    private DestroyRecordRepo       destroyRecordRepo;
+    private AirDropService          airDropService;
+    private HCChainService          hcChainService;
+    private RockRecordService       rockRecordService;
+    private RockRecordRepo          rockRecordRepo;
+    private AssetLockRepo           assetLockRepo;
+    private UserBalanceService      userBalanceService;
+    private PhotoAssetRepo          photoAssetRepo;
+    private NumberSeqRepo           numberSeqRepo;
 
 
     public Page<Asset> all(PageQuery pageQuery) {
     public Page<Asset> all(PageQuery pageQuery) {
 
 
@@ -264,7 +264,11 @@ public class AssetService {
         asset.setNumber(number);
         asset.setNumber(number);
         asset.setOrderId(orderId);
         asset.setOrderId(orderId);
         asset.setPrice(price);
         asset.setPrice(price);
-        asset.setPrefixName("RID");
+        if (domainOrder.getPicName().length() < 6) {
+            asset.setPrefixName("RID" + domainOrder.getPicName().length());
+        } else {
+            asset.setPrefixName("RID");
+        }
         asset.setTags(new HashSet<>());
         asset.setTags(new HashSet<>());
         User fakeUser = null;
         User fakeUser = null;
         if (safeFlag) {
         if (safeFlag) {
@@ -479,7 +483,7 @@ public class AssetService {
             throw new BusinessException("星图藏品不可寄售");
             throw new BusinessException("星图藏品不可寄售");
         }
         }
 
 
-        if (asset.getType().equals(CollectionType.DOMAIN)) {
+        if (!sysConfigService.getBoolean("domain_transfer")) {
             throw new BusinessException("域名暂不可以寄售");
             throw new BusinessException("域名暂不可以寄售");
         }
         }
 
 
@@ -494,22 +498,24 @@ public class AssetService {
             }
             }
         });
         });
 
 
-        int holdDays;
-        if (asset.getSource() == AssetSource.GIFT) {
-            LocalDateTime localDateTime = asset.getCreatedAt();
-            LocalDateTime gift_change_time = LocalDateTime
-                    .parse(sysConfigService.getString("gift_change_time"), DateTimeFormatter
-                            .ofPattern("yyyy-MM-dd HH:mm:ss"));
-            if (localDateTime.compareTo(gift_change_time) < 0) {
-                holdDays = 20;
-            } else {
-                holdDays = sysConfigService.getInt("gift_days");
-            }
-        } else {
-            if (ObjectUtils.isEmpty(asset.getHoldDays())) {
-                holdDays = sysConfigService.getInt("hold_days");
+        int holdDays = 0;
+        if (!asset.getType().equals(CollectionType.DOMAIN)) {
+            if (asset.getSource() == AssetSource.GIFT) {
+                LocalDateTime localDateTime = asset.getCreatedAt();
+                LocalDateTime gift_change_time = LocalDateTime
+                        .parse(sysConfigService.getString("gift_change_time"), DateTimeFormatter
+                                .ofPattern("yyyy-MM-dd HH:mm:ss"));
+                if (localDateTime.compareTo(gift_change_time) < 0) {
+                    holdDays = 20;
+                } else {
+                    holdDays = sysConfigService.getInt("gift_days");
+                }
             } else {
             } else {
-                holdDays = asset.getHoldDays();
+                if (ObjectUtils.isEmpty(asset.getHoldDays())) {
+                    holdDays = sysConfigService.getInt("hold_days");
+                } else {
+                    holdDays = asset.getHoldDays();
+                }
             }
             }
         }
         }
         if (holdDays == 0 && AssetSource.OFFICIAL.equals(asset.getSource())) {
         if (holdDays == 0 && AssetSource.OFFICIAL.equals(asset.getSource())) {
@@ -596,6 +602,9 @@ public class AssetService {
                 .prefixName(asset.getPrefixName())
                 .prefixName(asset.getPrefixName())
                 .companyId(asset.getCompanyId())
                 .companyId(asset.getCompanyId())
                 .build();
                 .build();
+        if (asset.getType().equals(CollectionType.DOMAIN)) {
+            collection.setType(CollectionType.DOMAIN);
+        }
         if (asset.getTags() != null) {
         if (asset.getTags() != null) {
             collection.getTags().addAll(asset.getTags());
             collection.getTags().addAll(asset.getTags());
         }
         }
@@ -735,6 +744,7 @@ public class AssetService {
         newAsset.setPublicShow(false);
         newAsset.setPublicShow(false);
         newAsset.setConsignment(false);
         newAsset.setConsignment(false);
         newAsset.setPublicCollectionId(null);
         newAsset.setPublicCollectionId(null);
+        asset.setTags(new HashSet<>());
         newAsset.setStatus(AssetStatus.NORMAL);
         newAsset.setStatus(AssetStatus.NORMAL);
         newAsset.setPrice(price);
         newAsset.setPrice(price);
         newAsset.setSellPrice(null);
         newAsset.setSellPrice(null);
@@ -742,9 +752,14 @@ public class AssetService {
         newAsset.setOasisId(asset.getOasisId());
         newAsset.setOasisId(asset.getOasisId());
         newAsset.setFromAssetId(asset.getId());
         newAsset.setFromAssetId(asset.getId());
         newAsset.setType(CollectionType.DEFAULT);
         newAsset.setType(CollectionType.DEFAULT);
+        if (asset.getType() == CollectionType.DOMAIN) {
+            newAsset.setType(CollectionType.DOMAIN);
+        }
 
 
         newAsset.setSource(TransferReason.GIFT == reason ? AssetSource.GIFT : AssetSource.TRANSFER);
         newAsset.setSource(TransferReason.GIFT == reason ? AssetSource.GIFT : AssetSource.TRANSFER);
-        newAsset.setTags(new HashSet<>(asset.getTags()));
+        if (!newAsset.getType().equals(CollectionType.DOMAIN)) {
+            newAsset.setTags(new HashSet<>(asset.getTags()));
+        }
         newAsset.setSafeFlag(safeFlag);
         newAsset.setSafeFlag(safeFlag);
         newAsset.setHoldDays(asset.getOldHoldDays());
         newAsset.setHoldDays(asset.getOldHoldDays());
         if (asset.getType().equals(CollectionType.PICTURE)) {
         if (asset.getType().equals(CollectionType.PICTURE)) {

+ 5 - 0
src/main/java/com/izouma/nineth/service/CacheService.java

@@ -75,6 +75,11 @@ public class CacheService {
     public void clearOrderPriceTrend() {
     public void clearOrderPriceTrend() {
     }
     }
 
 
+    @Scheduled(fixedRate = 600000)
+    @CacheEvict(value = "statisticDetail", allEntries = true)
+    public void clearStatisticDetail() {
+    }
+
     @CacheEvict(value = "top", key = "#month")
     @CacheEvict(value = "top", key = "#month")
     public void clearTop(int month) {
     public void clearTop(int month) {
     }
     }

+ 39 - 19
src/main/java/com/izouma/nineth/service/GiftOrderService.java

@@ -162,13 +162,26 @@ public class GiftOrderService {
 
 
     @Transactional
     @Transactional
     public GiftOrder gift(Long userId, Long assetId, Long toUserId, String tradeCode) {
     public GiftOrder gift(Long userId, Long assetId, Long toUserId, String tradeCode) {
-        if (BigDecimal.ZERO.compareTo(sysConfigService.getBigDecimal("gift_gas_fee")) == 0) {
-            return giftWithoutGasFee(userId, assetId, toUserId, tradeCode);
-        }
         Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("资产不存在"));
         Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("资产不存在"));
-        if (asset.getType().equals(CollectionType.DOMAIN)) {
-            throw new BusinessException("域名藏品暂不可以转赠");
+        BigDecimal gasFee;
+        if (asset.getType() != CollectionType.DOMAIN) {
+            gasFee = sysConfigService.getBigDecimal("gift_gas_fee");
+            if (BigDecimal.ZERO.compareTo(gasFee) == 0) {
+                return giftWithoutGasFee(userId, assetId, toUserId, tradeCode);
+            }
+        } else {
+            boolean open = sysConfigService.getBoolean("domain_transfer");
+            if (!open) {
+                throw new BusinessException("域名二级未开放");
+            }
+            gasFee = sysConfigService.getBigDecimal("domain_give_price");
+            if (BigDecimal.ZERO.compareTo(gasFee) == 0) {
+                return giftWithoutGasFee(userId, assetId, toUserId, tradeCode);
+            }
         }
         }
+//        if (asset.getType().equals(CollectionType.DOMAIN)) {
+//            throw new BusinessException("域名藏品暂不可以转赠");
+//        }
         if (!asset.getUserId().equals(userId)) {
         if (!asset.getUserId().equals(userId)) {
             throw new BusinessException("无权限");
             throw new BusinessException("无权限");
         }
         }
@@ -181,21 +194,28 @@ public class GiftOrderService {
         }
         }
 
 
         int holdDays;
         int holdDays;
-        if (asset.getSource() == AssetSource.GIFT) {
-            LocalDateTime localDateTime = asset.getCreatedAt();
-            LocalDateTime gift_change_time = LocalDateTime
-                    .parse(sysConfigService.getString("gift_change_time"), DateTimeFormatter
-                            .ofPattern("yyyy-MM-dd HH:mm:ss"));
-            if (localDateTime.isBefore(gift_change_time)) {
-                holdDays = 20;
-            } else {
-                holdDays = sysConfigService.getInt("gift_days");
-            }
+        if (asset.getType().equals(CollectionType.DOMAIN)) {
+            holdDays = sysConfigService.getInt("domain_gift");
         } else {
         } else {
-            if (ObjectUtils.isEmpty(asset.getHoldDays())) {
-                holdDays = sysConfigService.getInt("hold_days");
+            if (asset.getSource() == AssetSource.GIFT) {
+
+                LocalDateTime localDateTime = asset.getCreatedAt();
+                LocalDateTime gift_change_time = LocalDateTime
+                        .parse(sysConfigService.getString("gift_change_time"), DateTimeFormatter
+                                .ofPattern("yyyy-MM-dd HH:mm:ss"));
+                if (localDateTime.isBefore(gift_change_time)) {
+                    holdDays = 20;
+                } else {
+                    holdDays = sysConfigService.getInt("gift_days");
+                }
+
             } else {
             } else {
-                holdDays = asset.getHoldDays();
+                if (ObjectUtils.isEmpty(asset.getHoldDays())) {
+                    holdDays = sysConfigService.getInt("hold_days");
+                } else {
+                    holdDays = asset.getHoldDays();
+                }
+
             }
             }
         }
         }
 
 
@@ -234,7 +254,7 @@ public class GiftOrderService {
                 .userId(userId)
                 .userId(userId)
                 .assetId(assetId)
                 .assetId(assetId)
                 .toUserId(toUserId)
                 .toUserId(toUserId)
-                .gasPrice(sysConfigService.getBigDecimal("gift_gas_fee"))
+                .gasPrice(gasFee)
                 .status(OrderStatus.NOT_PAID)
                 .status(OrderStatus.NOT_PAID)
                 .companyId(asset.getCompanyId())
                 .companyId(asset.getCompanyId())
                 .build();
                 .build();

+ 5 - 1
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -399,7 +399,11 @@ public class OrderService {
                 //拥有指定藏品降税
                 //拥有指定藏品降税
                 Long sellerId = asset.getOwnerId();
                 Long sellerId = asset.getOwnerId();
                 order.setRoyalties(assetService.getRoyalties(minter.getId(), collection.getRoyalties(), sellerId));
                 order.setRoyalties(assetService.getRoyalties(minter.getId(), collection.getRoyalties(), sellerId));
-                order.setServiceCharge(assetService.getServicecharge(collection.getServiceCharge(), sellerId));
+                if (asset.getType().equals(CollectionType.DOMAIN)) {
+                    order.setServiceCharge(sysConfigService.getBigDecimal("domain_service_charge").doubleValue());
+                } else {
+                    order.setServiceCharge(assetService.getServicecharge(collection.getServiceCharge(), sellerId));
+                }
             }
             }
             order = orderRepo.save(order);
             order = orderRepo.save(order);
             if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
             if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {

+ 62 - 0
src/main/java/com/izouma/nineth/service/StatisticService.java

@@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
 
 
 import javax.xml.stream.events.EndDocument;
 import javax.xml.stream.events.EndDocument;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.sql.Timestamp;
 import java.sql.Timestamp;
 import java.time.*;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatter;
@@ -35,6 +36,8 @@ public class StatisticService {
     private OrderRepo         orderRepo;
     private OrderRepo         orderRepo;
     private TokenHistoryRepo  tokenHistoryRepo;
     private TokenHistoryRepo  tokenHistoryRepo;
     private BalanceRecordRepo balanceRecordRepo;
     private BalanceRecordRepo balanceRecordRepo;
+    private PhotoAssetRepo    photoAssetRepo;
+    private DomainOrderRepo   domainOrderRepo;
 
 
     public Map<String, Object> total(Long userId, Long companyId) {
     public Map<String, Object> total(Long userId, Long companyId) {
         User user1 = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
         User user1 = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
@@ -389,5 +392,64 @@ public class StatisticService {
                 .body();
                 .body();
     }
     }
 
 
+    public Map<String, Map<String, Object>> statisticDetail() {
+        Map<String, Map<String, Object>> result = new HashMap<>();
+        //今日
+        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
+        LocalDateTime todayEnd = LocalDateTime.now();
+        Map<String, Object> today = statisticDetail(todayStart, todayEnd);
+        result.put("today", today);
+        LocalDateTime lastStart = LocalDate.now().atStartOfDay().minusDays(1);
+        LocalDateTime lastEnd = LocalDate.now().atTime(LocalTime.MAX).minusDays(1);
+        Map<String, Object> last = statisticDetail(lastStart, lastEnd);
+        result.put("last", last);
+        LocalDateTime yesterStart = LocalDate.now().atStartOfDay().minusDays(2);
+        LocalDateTime yesterEnd = LocalDate.now().atTime(LocalTime.MAX).minusDays(2);
+        Map<String, Object> yesterday = statisticDetail(yesterStart, yesterEnd);
+        result.put("yesterday", yesterday);
+        return result;
+    }
 
 
+    public Map<String, Object> statisticDetail(LocalDateTime todayStart, LocalDateTime todayEnd) {
+        Map<String, Object> today = new HashMap<>();
+        //充值
+        BigDecimal rcToday = Optional.ofNullable(balanceRecordRepo.sumRechargeToday(todayStart, todayEnd))
+                .orElse(BigDecimal.ZERO);
+        today.put("recharge", rcToday);
+        //提现
+        BigDecimal wdToday = Optional.ofNullable(balanceRecordRepo.sumWithdrawToday(todayStart, todayEnd))
+                .orElse(BigDecimal.ZERO);
+        today.put("withdraw", wdToday);
+        //星图
+        BigDecimal paToday = Optional.ofNullable(photoAssetRepo.sumPaid(todayStart, todayEnd)).orElse(BigDecimal.ZERO);
+        today.put("photoAsset", paToday);
+        List<Order> orders = orderRepo.findAllByCreatedAtBetweenAndStatusInAndCompanyId(todayStart, todayEnd,
+                Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH), 1L);
+        ///手续费
+        List<BigDecimal> ros = new ArrayList<>();
+        List<BigDecimal> scs = new ArrayList<>();
+        for (Order order : orders) {
+            BigDecimal amount = order.getTotalPrice();
+            BigDecimal ro = BigDecimal.valueOf(order.getRoyalties());
+            BigDecimal sc = BigDecimal.valueOf(order.getServiceCharge());
+
+            BigDecimal orderRo = amount.multiply(ro).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN);
+            ros.add(orderRo);
+            BigDecimal orderSc = amount.multiply(sc).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN);
+            scs.add(orderSc);
+        }
+        BigDecimal todayRo = Optional.of(ros.stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO))
+                .orElse(BigDecimal.ZERO);
+        today.put("royalties", todayRo);
+        //版权费
+        BigDecimal todaySc = scs.stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+        today.put("serviceCharge", todaySc);
+        //域名
+        BigDecimal domainOrder = domainOrderRepo.sumToday(todayStart, todayEnd);
+        today.put("domainOrder", Optional.ofNullable(domainOrder).orElse(BigDecimal.ZERO));
+        //saas
+        BigDecimal saas = orderRepo.sumSaas(todayStart, todayEnd);
+        today.put("saas", Optional.ofNullable(saas).orElse(BigDecimal.ZERO));
+        return today;
+    }
 }
 }

+ 11 - 10
src/main/java/com/izouma/nineth/web/AssetController.java

@@ -11,10 +11,7 @@ import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.AssetRepo;
 import com.izouma.nineth.repo.AssetRepo;
 import com.izouma.nineth.repo.CollectionRepo;
 import com.izouma.nineth.repo.CollectionRepo;
 import com.izouma.nineth.repo.OrderRepo;
 import com.izouma.nineth.repo.OrderRepo;
-import com.izouma.nineth.service.AssetService;
-import com.izouma.nineth.service.CacheService;
-import com.izouma.nineth.service.GiftOrderService;
-import com.izouma.nineth.service.UserAssetSummaryService;
+import com.izouma.nineth.service.*;
 import com.izouma.nineth.utils.SecurityUtils;
 import com.izouma.nineth.utils.SecurityUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
@@ -39,13 +36,14 @@ import java.util.concurrent.ExecutionException;
 @RequestMapping("/asset")
 @RequestMapping("/asset")
 @AllArgsConstructor
 @AllArgsConstructor
 public class AssetController extends BaseController {
 public class AssetController extends BaseController {
-    private AssetService assetService;
-    private AssetRepo assetRepo;
-    private GiftOrderService giftOrderService;
-    private OrderRepo orderRepo;
-    private CacheService cacheService;
+    private AssetService            assetService;
+    private AssetRepo               assetRepo;
+    private GiftOrderService        giftOrderService;
+    private OrderRepo               orderRepo;
+    private CacheService            cacheService;
     private UserAssetSummaryService userAssetSummaryService;
     private UserAssetSummaryService userAssetSummaryService;
-    private CollectionRepo collectionRepo;
+    private CollectionRepo          collectionRepo;
+    private SysConfigService        sysConfigService;
 
 
     //@PreAuthorize("hasRole('ADMIN')")
     //@PreAuthorize("hasRole('ADMIN')")
 //    @PostMapping("/save")
 //    @PostMapping("/save")
@@ -234,6 +232,9 @@ public class AssetController extends BaseController {
     @PostMapping("/getServicecharge")
     @PostMapping("/getServicecharge")
     public double getServicecharge(@RequestParam Long id) {
     public double getServicecharge(@RequestParam Long id) {
         Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
         Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+        if (asset.getType().equals(CollectionType.DOMAIN)) {
+            return sysConfigService.getBigDecimal("domain_service_charge").doubleValue();
+        }
         return assetService.getServicecharge(asset.getServiceCharge(), SecurityUtils.getAuthenticatedUser()
         return assetService.getServicecharge(asset.getServiceCharge(), SecurityUtils.getAuthenticatedUser()
                 .getId());
                 .getId());
     }
     }

+ 6 - 0
src/main/java/com/izouma/nineth/web/StatisticController.java

@@ -114,4 +114,10 @@ public class StatisticController {
     public Map<String, Object> otherStatistic() {
     public Map<String, Object> otherStatistic() {
         return statisticService.otherStatistic();
         return statisticService.otherStatistic();
     }
     }
+
+    @GetMapping("/statisticDetail")
+    @Cacheable("statisticDetail")
+    public Map<String, Map<String, Object>> statisticDetail() {
+        return statisticService.statisticDetail();
+    }
 }
 }

+ 7 - 1
src/main/vue/src/main.js

@@ -79,9 +79,12 @@ Vue.component('created-at-picker', CreatedAtPicker);
 Vue.mixin(Formatters);
 Vue.mixin(Formatters);
 Vue.mixin({
 Vue.mixin({
     computed: {
     computed: {
-        ...mapGetters(['companyId']),
+        ...mapGetters(['companyId', 'meta']),
         isCompany() {
         isCompany() {
             return this.companyId > 1;
             return this.companyId > 1;
+        },
+        isMeta() {
+            return this.meta === 'true';
         }
         }
     }
     }
 });
 });
@@ -97,3 +100,6 @@ let query = queryString.parse(location.search);
 if (query.companyId) {
 if (query.companyId) {
     sessionStorage.setItem('companyId', query.companyId);
     sessionStorage.setItem('companyId', query.companyId);
 }
 }
+if (query.meta) {
+    sessionStorage.setItem('meta', query.meta);
+}

+ 16 - 0
src/main/vue/src/router.js

@@ -1036,6 +1036,22 @@ const router = new Router({
                         title: '企业管理员'
                         title: '企业管理员'
                     }
                     }
                 },
                 },
+                {
+                    path: '/metaCompanyEdit',
+                    name: 'MetaCompanyEdit',
+                    component: () => import(/* webpackChunkName: "metaCompanyEdit" */ '@/views/MetaCompanyEdit.vue'),
+                    meta: {
+                        title: '元宇宙企业管理编辑'
+                    }
+                },
+                {
+                    path: '/metaCompanyList',
+                    name: 'MetaCompanyList',
+                    component: () => import(/* webpackChunkName: "metaCompanyList" */ '@/views/MetaCompanyList.vue'),
+                    meta: {
+                        title: '元宇宙企业管理'
+                    }
+                },
                 {
                 {
                     path: '/companyCollectionEdit',
                     path: '/companyCollectionEdit',
                     name: 'CompanyCollectionEdit',
                     name: 'CompanyCollectionEdit',

+ 6 - 0
src/main/vue/src/store.js

@@ -29,6 +29,12 @@ export default new Vuex.Store({
                 return state.userInfo.companyId || 1;
                 return state.userInfo.companyId || 1;
             }
             }
             return 1;
             return 1;
+        },
+        meta(state) {
+            if (sessionStorage.getItem('meta')) {
+                return sessionStorage.getItem('meta');
+            }
+            return false;
         }
         }
     }
     }
 });
 });

File diff suppressed because it is too large
+ 593 - 489
src/main/vue/src/views/Admin.vue


+ 7 - 7
src/main/vue/src/views/CollectionEdit.vue

@@ -70,10 +70,10 @@
                     <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
                     <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
                         <rich-text v-model="formData.detail"></rich-text>
                         <rich-text v-model="formData.detail"></rich-text>
                     </el-form-item>
                     </el-form-item>
-                    <el-form-item prop="empower" label="赋能列表" style="width: calc(100vw - 450px)">
+                    <el-form-item prop="empower" label="赋能列表" style="width: calc(100vw - 450px)" v-if="!isMeta">
                         <rich-text v-model="formData.empower"></rich-text>
                         <rich-text v-model="formData.empower"></rich-text>
                     </el-form-item>
                     </el-form-item>
-                    <el-form-item prop="properties" label="特性" style="width: calc(100vw - 450px)" size="mini">
+                    <el-form-item prop="properties" label="特性" style="width: calc(100vw - 450px)" size="mini" v-if="!isMeta">
                         <el-table :data="formData.properties">
                         <el-table :data="formData.properties">
                             <el-table-column prop="name" label="名称">
                             <el-table-column prop="name" label="名称">
                                 <template v-slot="{ row }">
                                 <template v-slot="{ row }">
@@ -97,7 +97,7 @@
                     <el-form-item>
                     <el-form-item>
                         <el-button size="mini" @click="addProperty"> 添加特性 </el-button>
                         <el-button size="mini" @click="addProperty"> 添加特性 </el-button>
                     </el-form-item>
                     </el-form-item>
-                    <el-form-item label="特权" prop="privileges" style="width: calc(100vw - 450px)">
+                    <el-form-item label="特权" prop="privileges" style="width: calc(100vw - 450px)" v-if="!isMeta">
                         <el-table :data="privilegeOptions">
                         <el-table :data="privilegeOptions">
                             <el-table-column prop="name" label="可选特权" width="150"></el-table-column>
                             <el-table-column prop="name" label="可选特权" width="150"></el-table-column>
                             <el-table-column prop="description"></el-table-column>
                             <el-table-column prop="description"></el-table-column>
@@ -161,7 +161,7 @@
                         </el-form-item>
                         </el-form-item>
                     </div>
                     </div>
                     <div class="inline-wrapper">
                     <div class="inline-wrapper">
-                        <el-form-item prop="royalties" label="版税(%)">
+                        <el-form-item prop="royalties" label="版税(%)" v-if="!isMeta">
                             <el-input-number v-model="formData.royalties" :min="0" :max="isCompany ? 10 : 99" :disabled="!canEdit">
                             <el-input-number v-model="formData.royalties" :min="0" :max="isCompany ? 10 : 99" :disabled="!canEdit">
                             </el-input-number>
                             </el-input-number>
                         </el-form-item>
                         </el-form-item>
@@ -195,7 +195,7 @@
                     <!-- <el-form-item prop="likes" label="点赞">
                     <!-- <el-form-item prop="likes" label="点赞">
                         <el-input-number v-model="formData.likes"></el-input-number>
                         <el-input-number v-model="formData.likes"></el-input-number>
                     </el-form-item> -->
                     </el-form-item> -->
-                    <el-form-item prop="scanCode" label="仅扫码可见">
+                    <el-form-item prop="scanCode" label="仅扫码可见" v-if="!isMeta">
                         <el-radio v-model="formData.scanCode" :label="true">是</el-radio>
                         <el-radio v-model="formData.scanCode" :label="true">是</el-radio>
                         <el-radio v-model="formData.scanCode" :label="false">否</el-radio>
                         <el-radio v-model="formData.scanCode" :label="false">否</el-radio>
                     </el-form-item>
                     </el-form-item>
@@ -245,7 +245,7 @@
                         </el-form-item>
                         </el-form-item>
                     </div>
                     </div>
 
 
-                    <el-form-item prop="holdDays" label="持有天数">
+                    <el-form-item prop="holdDays" label="持有天数" v-if="!isMeta">
                         <el-input-number
                         <el-input-number
                             type="number"
                             type="number"
                             :min="0"
                             :min="0"
@@ -334,7 +334,7 @@
                     <el-form-item label="活动规则" v-if="formData.assignment > 0">
                     <el-form-item label="活动规则" v-if="formData.assignment > 0">
                         <rich-text style="width:500px" onlyText v-model="formData.rule"></rich-text>
                         <rich-text style="width:500px" onlyText v-model="formData.rule"></rich-text>
                     </el-form-item>
                     </el-form-item>
-                    <el-form-item prop="newsId" label="新闻">
+                    <el-form-item prop="newsId" label="新闻"  v-if="!isMeta">
                         <el-select v-model="formData.newsId" placeholder="请选择">
                         <el-select v-model="formData.newsId" placeholder="请选择">
                             <el-option
                             <el-option
                                 v-for="item in newsOptions"
                                 v-for="item in newsOptions"

+ 1 - 1
src/main/vue/src/views/CompanyEdit.vue

@@ -114,7 +114,7 @@ export default {
         },
         },
         submit() {
         submit() {
             let data = { ...this.formData };
             let data = { ...this.formData };
-
+            data.meta = false
             this.saving = true;
             this.saving = true;
             this.$http
             this.$http
                 .post('/company/save', data, { body: 'json' })
                 .post('/company/save', data, { body: 'json' })

+ 3 - 3
src/main/vue/src/views/CompanyList.vue

@@ -117,7 +117,7 @@ export default {
     },
     },
     methods: {
     methods: {
         beforeGetData() {
         beforeGetData() {
-            return { search: this.search, query: { del: false } };
+            return { search: this.search, query: { del: false, meta: false } };
         },
         },
         toggleMultipleMode(multipleMode) {
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
             this.multipleMode = multipleMode;
@@ -146,7 +146,7 @@ export default {
             this.$axios
             this.$axios
                 .get('/company/excel', {
                 .get('/company/excel', {
                     responseType: 'blob',
                     responseType: 'blob',
-                    params: { size: 10000 }
+                    params: { size: 10000 , query: { del: false, meta: false } }
                 })
                 })
                 .then(res => {
                 .then(res => {
                     console.log(res);
                     console.log(res);
@@ -198,7 +198,7 @@ export default {
             });
             });
         },
         },
         admin(row) {
         admin(row) {
-            window.open(`/admin?companyId=${row.id}&from=super`, '_blank');
+            window.open(`/admin?companyId=${row.id}&meta=false&from=super`, '_blank');
         }
         }
     }
     }
 };
 };

+ 7 - 2
src/main/vue/src/views/Dashboard.vue

@@ -102,6 +102,7 @@ import TopWidget from '../widgets/TopWidget';
 import UserHoldTop from '../widgets/UserHoldTop';
 import UserHoldTop from '../widgets/UserHoldTop';
 import MonthWidget from '../widgets/MonthWidget';
 import MonthWidget from '../widgets/MonthWidget';
 import OtherStatistic from '../widgets/OtherStatistic';
 import OtherStatistic from '../widgets/OtherStatistic';
+import Detail from '../widgets/Detail';
 
 
 export default {
 export default {
     created() {},
     created() {},
@@ -133,7 +134,10 @@ export default {
                     { x: 6, y: 20, w: 6, h: 10, i: '7', name: 'TopWidget' },
                     { x: 6, y: 20, w: 6, h: 10, i: '7', name: 'TopWidget' },
                     { x: 6, y: 20, w: 12, h: 10, i: '9', name: 'UserHoldTop' }
                     { x: 6, y: 20, w: 12, h: 10, i: '9', name: 'UserHoldTop' }
                 ];
                 ];
-                this.layout2 = [{ x: 6, y: 0, w: 12, h: 12, i: '10', name: 'OtherStatistic' }];
+                this.layout2 = [
+                    { x: 6, y: 0, w: 12, h: 12, i: '10', name: 'OtherStatistic' },
+                    { x: 6, y: 12, w: 12, h: 12, i: '11', name: 'Detail' }
+                    ];
             } else {
             } else {
                 this.layout = [
                 this.layout = [
                     { x: 0, y: 0, w: 6, h: 4, i: '2', name: 'PriceWidget' },
                     { x: 0, y: 0, w: 6, h: 4, i: '2', name: 'PriceWidget' },
@@ -166,7 +170,8 @@ export default {
         TopWidget,
         TopWidget,
         MonthWidget,
         MonthWidget,
         UserHoldTop,
         UserHoldTop,
-        OtherStatistic
+        OtherStatistic,
+        Detail
     }
     }
 };
 };
 </script>
 </script>

+ 151 - 0
src/main/vue/src/views/MetaCompanyEdit.vue

@@ -0,0 +1,151 @@
+<template>
+    <div class="edit-view">
+        <page-title>
+            <el-button @click="$router.go(-1)" :disabled="saving">取消</el-button>
+            <el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id">
+                删除
+            </el-button>
+            <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
+        </page-title>
+        <div class="edit-view__content-wrapper">
+            <div class="edit-view__content-section">
+                <el-form
+                    :model="formData"
+                    :rules="rules"
+                    ref="form"
+                    label-width="80px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px;"
+                >
+                    <el-form-item prop="name" label="名称">
+                        <el-input v-model="formData.name"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="description" label="描述">
+                        <el-input type="textarea" v-model="formData.description"></el-input>
+                    </el-form-item>
+                    <el-form-item prop="logo" label="LOGO">
+                        <single-upload v-model="formData.logo"></single-upload>
+                    </el-form-item>
+                    <el-form-item prop="disabled" label="禁用">
+                        <el-switch v-model="formData.disabled"></el-switch>
+                    </el-form-item>
+                    <el-form-item label="功能权限">
+                        <el-checkbox v-model="formData.airdrop">空投</el-checkbox>
+                        <el-checkbox v-model="formData.mintActivity">铸造活动</el-checkbox>
+                    </el-form-item>
+                    <el-form-item class="form-submit">
+                        <el-button @click="onSave" :loading="saving" type="primary">
+                            保存
+                        </el-button>
+                        <el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id">
+                            删除
+                        </el-button>
+                        <el-button @click="$router.go(-1)" :disabled="saving">取消</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    name: ' MetaCompanyEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('company/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            saving: false,
+            formData: {
+                disabled: false
+            },
+            rules: {
+                name: [
+                    {
+                        required: true,
+                        message: '请输入名称',
+                        trigger: 'blur'
+                    }
+                ],
+                logo: [
+                    {
+                        required: true,
+                        message: '请输入LOGO',
+                        trigger: 'blur'
+                    }
+                ],
+                adminUserId: [
+                    {
+                        required: true,
+                        message: '请输入管理员',
+                        trigger: 'blur'
+                    }
+                ],
+                disabled: [
+                    {
+                        required: true,
+                        message: '请输入禁用',
+                        trigger: 'blur'
+                    }
+                ]
+            }
+        };
+    },
+    methods: {
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
+            data.meta = true
+            this.saving = true;
+            this.$http
+                .post('/company/save', data, { body: 'json' })
+                .then(res => {
+                    this.saving = false;
+                    this.$message.success('成功');
+                    this.$router.go(-1);
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.saving = false;
+                    this.$message.error(e.error);
+                });
+        },
+        onDelete() {
+            this.$confirm('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/company/del/${this.formData.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.$router.go(-1);
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        console.log(e);
+                        this.$message.error((e || {}).error || '删除失败');
+                    }
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 198 - 0
src/main/vue/src/views/MetaCompanyList.vue

@@ -0,0 +1,198 @@
+<template>
+    <div class="list-view">
+        <page-title>
+            <el-button
+                @click="addRow"
+                type="primary"
+                icon="el-icon-plus"
+                :disabled="fetchingData || downloading"
+                class="filter-item"
+            >
+                新增
+            </el-button>
+            <el-button
+                @click="download"
+                icon="el-icon-upload2"
+                :loading="downloading"
+                :disabled="fetchingData"
+                class="filter-item"
+            >
+                导出
+            </el-button>
+        </page-title>
+        <div class="filters-container">
+            <el-input
+                placeholder="搜索..."
+                v-model="search"
+                clearable
+                class="filter-item search"
+                @keyup.enter.native="getData"
+            >
+                <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
+            </el-input>
+        </div>
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+            v-loading="fetchingData"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="name" label="名称"> </el-table-column>
+            <el-table-column prop="description" label="描述"> </el-table-column>
+            <el-table-column prop="logo" label="LOGO">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.logo"
+                        fit="cover"
+                        :preview-src-list="[row.logo]"
+                    ></el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="adminUserId" label="管理员"> </el-table-column>
+            <el-table-column prop="disabled" label="禁用">
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.disabled ? '' : 'info'">{{ row.disabled }}</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="300">
+                <template slot-scope="{ row }">
+                    <el-button @click="adminMgmt(row)" size="mini">管理员</el-button>
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
+                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+                    <el-button @click="admin(row)" size="mini" type="">后台</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
+            </el-pagination>
+        </div>
+        <el-dialog title="管理员"></el-dialog>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+    name: 'MetaCompanyList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/company/all',
+            downloading: false
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeGetData() {
+            return { search: this.search, query: { del: false, meta: true } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaCompanyEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaCompanyEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/company/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false, meta: true } }
+                })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/company/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        },
+        adminMgmt(row) {
+            this.$router.push({
+                path: '/companyAdmin',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        admin(row) {
+            window.open(`/admin?companyId=${row.id}&meta=true&from=super`, '_blank');
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 132 - 0
src/main/vue/src/widgets/Detail.vue

@@ -0,0 +1,132 @@
+<template>
+    <widget-card :bodyStyle="bodyStyle">
+        <template #header>
+            <div class="header">
+                <span>流水明细</span>
+<!--                <el-select-->
+<!--                    style="width: 120px;"-->
+<!--                    size="mini"-->
+<!--                    v-model="value"-->
+<!--                    @change="changeSelect"-->
+<!--                    placeholder="请选择"-->
+<!--                >-->
+<!--                    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">-->
+<!--                    </el-option>-->
+<!--                </el-select>-->
+            </div>
+        </template>
+        <div class="box-content">
+            <div class="box">
+                <div class="text1">手续费/充值/saas/版权/星图/提现/域名</div>
+                <div class="text2">{{ order.serviceCharge }}元/{{ order.recharge }}元/{{ order.saas }}元/{{ order.royalties }}元/{{ order.photoAsset }}元/{{ order.withdraw }}元/{{ order.domainOrder }}元</div>
+            </div>
+        </div>
+    </widget-card>
+</template>
+<script>
+import WidgetCard from './WidgetCard';
+import acc from '../mixins/acc';
+
+export default {
+    created() {
+        this.getPriceInfo();
+        // this.value = 'today';
+        // this.changeSelect();
+    },
+    data() {
+        return {
+            bodyStyle: {
+                overflow: 'auto'
+            },
+            value: '',
+            priceInfo: {},
+            options: [
+                {label: 'today', value: 'today'},
+                {label: 'last', value: 'last'},
+                {label: 'yesterday', value: 'yesterday'},
+            ],
+            order: {}
+        };
+    },
+    mixins: [acc],
+    components: {
+        WidgetCard
+    },
+    mounted() {
+        // this.changeSelect();
+    },
+    methods: {
+        getPriceInfo() {
+            this.$http
+                .get('/statistic/statisticDetail')
+                .then(res => {
+                    this.order = res.today;
+                });
+        },
+        // changeSelect() {
+        //     this.order = this.priceInfo.today;
+        // }
+    }
+};
+</script>
+<style lang="less" scoped>
+.header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+
+/deep/ .el-card {
+    overflow: hidden;
+}
+
+.box-content {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    align-self: stretch;
+    padding: 30px;
+    height: 100%;
+    box-sizing: border-box;
+}
+
+.box {
+    padding: 0 20px;
+    height: 125px;
+    background: #f5f7fa;
+    border-radius: 16px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    min-width: 153px;
+    box-sizing: border-box;
+
+    .text1 {
+        font-size: 14px;
+        font-weight: bold;
+        color: #666666;
+        line-height: 20px;
+        white-space: nowrap;
+    }
+
+    .text2 {
+        color: #feb30e;
+        font-size: 22px;
+        font-weight: bold;
+        line-height: 29px;
+        margin-top: 2px;
+        white-space: nowrap;
+
+        /deep/ small {
+            font-size: 12px;
+        }
+    }
+
+    &:nth-child(2) {
+        .text2 {
+            color: #4dcc6f;
+        }
+    }
+}
+</style>

Some files were not shown because too many files changed in this diff