Просмотр исходного кода

Merge branch 'master' of http://git.izouma.com/xiongzhu/raex_back into dev-meta

 Conflicts:
	src/main/vue/src/router.js
sunkean 3 лет назад
Родитель
Сommit
efb73a119d

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

@@ -22,9 +22,14 @@ public class MetaEmail extends BaseEntity{
 
 
     @ApiModelProperty("邮件作者")
     @ApiModelProperty("邮件作者")
     @ExcelProperty("邮件作者")
     @ExcelProperty("邮件作者")
-    private String auther;
+    private String author;
 
 
     @ApiModelProperty("邮件内容")
     @ApiModelProperty("邮件内容")
     @ExcelProperty("邮件内容")
     @ExcelProperty("邮件内容")
     private String description;
     private String description;
+
+    @ApiModelProperty("是否发布")
+    @ExcelProperty("是否发布")
+    private boolean publish;
 }
 }
+

+ 26 - 0
src/main/java/com/izouma/nineth/domain/MetaZouMaLight.java

@@ -0,0 +1,26 @@
+package com.izouma.nineth.domain;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@ApiModel("元宇宙走马灯配置")
+public class MetaZouMaLight extends BaseEntity {
+
+    @ApiModelProperty("是否发布")
+    @ExcelProperty("是否发布")
+    private boolean publish;
+
+    @ApiModelProperty("走马灯详情")
+    @ExcelProperty("走马灯详情")
+    private String description;
+}

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

@@ -6,7 +6,9 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
@@ -21,4 +23,12 @@ public interface BalanceRecordRepo extends JpaRepository<BalanceRecord, Long>, J
     BalanceRecord findByOrderIdAndType(Long orderId, BalanceType type);
     BalanceRecord findByOrderIdAndType(Long orderId, BalanceType type);
 
 
     List<BalanceRecord> findByType(BalanceType type);
     List<BalanceRecord> findByType(BalanceType type);
+
+    List<BalanceRecord> findByTypeAndCreatedAtBetween(BalanceType type, LocalDateTime start, LocalDateTime end);
+
+    @Query("select sum(b.amount) from BalanceRecord b where b.type = 'RECHARGE' and b.del = false ")
+    BigDecimal sumRechargeAll();
+
+    @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);
 }
 }

+ 18 - 0
src/main/java/com/izouma/nineth/repo/MetaZoumaLightRepo.java

@@ -0,0 +1,18 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.domain.MetaZouMaLight;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import javax.transaction.Transactional;
+
+public interface MetaZoumaLightRepo extends JpaRepository<MetaZouMaLight, Long>, JpaSpecificationExecutor<MetaZouMaLight> {
+    @Query("update MetaZouMaLight t set t.del = true where t.id = ?1")
+    @Modifying
+    @Transactional
+    void softDelete(Long id);
+
+    MetaZouMaLight findByPublishAndDel (boolean publish, boolean del);
+}

+ 20 - 0
src/main/java/com/izouma/nineth/service/MetaZoumaLightService.java

@@ -0,0 +1,20 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.domain.MetaZouMaLight;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.repo.MetaZoumaLightRepo;
+import com.izouma.nineth.utils.JpaUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class MetaZoumaLightService {
+
+    private MetaZoumaLightRepo metaZoumaLightRepo;
+
+    public Page<MetaZouMaLight> all(PageQuery pageQuery) {
+        return metaZoumaLightRepo.findAll(JpaUtils.toSpecification(pageQuery, MetaZouMaLight.class), JpaUtils.toPageRequest(pageQuery));
+    }
+}

+ 3 - 3
src/main/java/com/izouma/nineth/service/OrderPayService.java

@@ -439,9 +439,9 @@ public class OrderPayService {
         if (amount.compareTo(minAmount) < 0) {
         if (amount.compareTo(minAmount) < 0) {
             throw new BusinessException("充值金额不能小于" + minAmount);
             throw new BusinessException("充值金额不能小于" + minAmount);
         }
         }
-        if (amount.compareTo(new BigDecimal("50000")) > 0) {
-            throw new BusinessException("充值金额不能大于50000");
-        }
+//        if (amount.compareTo(new BigDecimal("50000")) > 0) {
+//            throw new BusinessException("充值金额不能大于50000");
+//        }
         RechargeOrder order = RechargeOrder.builder()
         RechargeOrder order = RechargeOrder.builder()
                 .id(snowflakeIdWorker.nextId())
                 .id(snowflakeIdWorker.nextId())
                 .userId(userId)
                 .userId(userId)

+ 25 - 8
src/main/java/com/izouma/nineth/service/StatisticService.java

@@ -2,17 +2,19 @@ package com.izouma.nineth.service;
 
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
+import com.izouma.nineth.domain.BalanceRecord;
 import com.izouma.nineth.domain.Order;
 import com.izouma.nineth.domain.Order;
+import com.izouma.nineth.domain.RechargeOrder;
 import com.izouma.nineth.domain.User;
 import com.izouma.nineth.domain.User;
+import com.izouma.nineth.enums.BalanceType;
 import com.izouma.nineth.enums.CollectionSource;
 import com.izouma.nineth.enums.CollectionSource;
 import com.izouma.nineth.enums.OrderStatus;
 import com.izouma.nineth.enums.OrderStatus;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.exception.BusinessException;
-import com.izouma.nineth.repo.OrderRepo;
-import com.izouma.nineth.repo.TokenHistoryRepo;
-import com.izouma.nineth.repo.UserRepo;
+import com.izouma.nineth.repo.*;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
+import javax.xml.stream.events.EndDocument;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
@@ -26,9 +28,10 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 @AllArgsConstructor
 public class StatisticService {
 public class StatisticService {
 
 
-    private UserRepo         userRepo;
-    private OrderRepo        orderRepo;
-    private TokenHistoryRepo tokenHistoryRepo;
+    private UserRepo          userRepo;
+    private OrderRepo         orderRepo;
+    private TokenHistoryRepo  tokenHistoryRepo;
+    private BalanceRecordRepo balanceRecordRepo;
 
 
     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("无用户"));
@@ -39,6 +42,8 @@ public class StatisticService {
             long user = userRepo.countAllByDelFalse();
             long user = userRepo.countAllByDelFalse();
             total.put("userNum", user);
             total.put("userNum", user);
             orders = orderRepo.findAllByStatusAndCompanyId(OrderStatus.FINISH, companyId);
             orders = orderRepo.findAllByStatusAndCompanyId(OrderStatus.FINISH, companyId);
+            BigDecimal allRecharged = balanceRecordRepo.sumRechargeAll();
+            total.put("rechargePrice", allRecharged);
         } else {
         } else {
             orders = orderRepo.findAllByStatusAndMinterId(OrderStatus.FINISH, userId);
             orders = orderRepo.findAllByStatusAndMinterId(OrderStatus.FINISH, userId);
         }
         }
@@ -132,9 +137,20 @@ public class StatisticService {
 
 
         User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
         User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
         List<Order> orders;
         List<Order> orders;
+        Map<String, Map<String, BigDecimal>> trend = new HashMap<>();
         if (user.isAdmin()) {
         if (user.isAdmin()) {
             orders = orderRepo.findAllByCreatedAtIsAfterAndStatusInAndCompanyId(start,
             orders = orderRepo.findAllByCreatedAtIsAfterAndStatusInAndCompanyId(start,
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH), companyId);
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH), companyId);
+            List<BalanceRecord> balanceRecords = balanceRecordRepo
+                    .findByTypeAndCreatedAtBetween(BalanceType.RECHARGE, start, LocalDateTime.now());
+            Map<String, BigDecimal> recharged = null;
+            if (balanceRecords.size() > 0) {
+                recharged = balanceRecords.stream()
+                        .collect(Collectors.groupingBy(item -> DateTimeFormatter.ofPattern("yyyy-MM-dd")
+                                .format(item.getCreatedAt()), Collectors.mapping(BalanceRecord::getAmount,
+                                Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+            }
+            trend.put("recharged", recharged);
         } else {
         } else {
             orders = orderRepo.findAllByCreatedAtIsAfterAndMinterIdAndStatusIn(start, userId,
             orders = orderRepo.findAllByCreatedAtIsAfterAndMinterIdAndStatusIn(start, userId,
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH));
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH));
@@ -161,7 +177,6 @@ public class StatisticService {
                                     Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
                                     Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
         }
         }
 
 
-        Map<String, Map<String, BigDecimal>> trend = new HashMap<>();
         trend.put("official", official);
         trend.put("official", official);
         trend.put("transfer", transfer);
         trend.put("transfer", transfer);
         return trend;
         return trend;
@@ -179,14 +194,16 @@ public class StatisticService {
 
 
         User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
         User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
         List<Order> orders;
         List<Order> orders;
+        Map<String, BigDecimal> map = new HashMap<>();
         if (user.isAdmin()) {
         if (user.isAdmin()) {
             orders = orderRepo.findAllByCreatedAtBetweenAndStatusInAndCompanyId(start, end,
             orders = orderRepo.findAllByCreatedAtBetweenAndStatusInAndCompanyId(start, end,
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH), companyId);
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH), companyId);
+            BigDecimal allRecharged = balanceRecordRepo.sumRechargeToday(start, end);
+            map.put("recharged", allRecharged);
         } else {
         } else {
             orders = orderRepo.findAllByCreatedAtBetweenAndMinterIdAndStatusIn(start, end, userId,
             orders = orderRepo.findAllByCreatedAtBetweenAndMinterIdAndStatusIn(start, end, userId,
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH));
                     Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH));
         }
         }
-        Map<String, BigDecimal> map = new HashMap<>();
         map.put("official", orders.stream().filter(order -> order.getSource().equals(CollectionSource.OFFICIAL))
         map.put("official", orders.stream().filter(order -> order.getSource().equals(CollectionSource.OFFICIAL))
                 .map(Order::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
                 .map(Order::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
         map.put("transfer", orders.stream().filter(order -> order.getSource().equals(CollectionSource.TRANSFER))
         map.put("transfer", orders.stream().filter(order -> order.getSource().equals(CollectionSource.TRANSFER))

+ 4 - 1
src/main/java/com/izouma/nineth/service/netease/TeamService.java

@@ -189,6 +189,10 @@ public class TeamService {
         List<String> ids = new ArrayList<>();
         List<String> ids = new ArrayList<>();
         ids.add(id);
         ids.add(id);
         Team team = teamRepo.findById(Long.valueOf(tid)).orElseThrow(new BusinessException("未找到群聊"));
         Team team = teamRepo.findById(Long.valueOf(tid)).orElseThrow(new BusinessException("未找到群聊"));
+        List<String> members = new ArrayList<>(team.getMembers());
+        if (members.size() > 199) {
+            throw new BusinessException("群成员已满");
+        }
         List<String> kicked = team.getKicked();
         List<String> kicked = team.getKicked();
         if (kicked.stream().anyMatch(member -> StringUtils.equals(member, id))) {
         if (kicked.stream().anyMatch(member -> StringUtils.equals(member, id))) {
             throw new BusinessException("用户被踢出,无法加入");
             throw new BusinessException("用户被踢出,无法加入");
@@ -207,7 +211,6 @@ public class TeamService {
         if (code != 200) {
         if (code != 200) {
             throw new BusinessException("群成员已满,无法加入");
             throw new BusinessException("群成员已满,无法加入");
         }
         }
-        List<String> members = new ArrayList<>(team.getMembers());
         members.add(id);
         members.add(id);
         team.setMembers(members);
         team.setMembers(members);
         return teamRepo.save(team);
         return teamRepo.save(team);

+ 1 - 1
src/main/java/com/izouma/nineth/web/CollectionController.java

@@ -241,7 +241,7 @@ public class CollectionController extends BaseController {
         map.put("onlyShowNum", String.valueOf(onlyShowNum));
         map.put("onlyShowNum", String.valueOf(onlyShowNum));
         map.put("consignmentNum", String.valueOf(consignmentNum));
         map.put("consignmentNum", String.valueOf(consignmentNum));
         map.put("transactingNum", String.valueOf(transactingNum));
         map.put("transactingNum", String.valueOf(transactingNum));
-        map.put("tranferingNum", String.valueOf(tranferCount));
+        map.put("tranferingNum", String.valueOf(tranferCount - 1));
         return map;
         return map;
     }
     }
 }
 }

+ 8 - 2
src/main/java/com/izouma/nineth/web/MetaEmailController.java

@@ -1,14 +1,13 @@
 package com.izouma.nineth.web;
 package com.izouma.nineth.web;
 import com.izouma.nineth.domain.MetaEmail;
 import com.izouma.nineth.domain.MetaEmail;
-import com.izouma.nineth.service.MetaEmailService;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.MetaEmailRepo;
 import com.izouma.nineth.repo.MetaEmailRepo;
+import com.izouma.nineth.service.MetaEmailService;
 import com.izouma.nineth.utils.ObjUtils;
 import com.izouma.nineth.utils.ObjUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
@@ -56,5 +55,12 @@ public class MetaEmailController extends BaseController {
         List<MetaEmail> data = all(pageQuery).getContent();
         List<MetaEmail> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data);
         ExcelUtils.export(response, data);
     }
     }
+
+    @PostMapping("/{id}/publish")
+    public void publish(@PathVariable Long id) {
+        MetaEmail metaEmail = metaEmailRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+        metaEmail.setPublish(true);
+        metaEmailRepo.save(metaEmail);
+    }
 }
 }
 
 

+ 66 - 0
src/main/java/com/izouma/nineth/web/MetaZoumaLightController.java

@@ -0,0 +1,66 @@
+package com.izouma.nineth.web;
+import com.izouma.nineth.domain.MetaZouMaLight;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.MetaZoumaLightRepo;
+import com.izouma.nineth.service.MetaZoumaLightService;
+import com.izouma.nineth.utils.ObjUtils;
+import com.izouma.nineth.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+@RestController
+@RequestMapping("/metaZoumaLight")
+@AllArgsConstructor
+public class MetaZoumaLightController extends BaseController {
+    private MetaZoumaLightService metaZoumaLightService;
+    private MetaZoumaLightRepo metaZoumaLightRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public MetaZouMaLight save(@RequestBody MetaZouMaLight record) {
+        if (record.isPublish()) {
+            MetaZouMaLight metaZoumaLight = metaZoumaLightRepo.findByPublishAndDel(true,false);
+            if (Objects.nonNull(metaZoumaLight) && !Objects.equals(metaZoumaLight.getId(), record.getId())){
+                throw new BusinessException("仅允许发布一条!");
+            }
+        }
+        if (record.getId() != null) {
+            MetaZouMaLight orig = metaZoumaLightRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return metaZoumaLightRepo.save(orig);
+        }
+        return metaZoumaLightRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<MetaZouMaLight> all(@RequestBody PageQuery pageQuery) {
+        return metaZoumaLightService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public MetaZouMaLight get(@PathVariable Long id) {
+        return metaZoumaLightRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        metaZoumaLightRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<MetaZouMaLight> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 4 - 4
src/main/java/com/izouma/nineth/web/netease/TeamController.java

@@ -39,25 +39,25 @@ public class TeamController extends BaseController {
         return teamService.create(record);
         return teamService.create(record);
     }
     }
 
 
-    @PreAuthorize("hasRole('ADMIN')")
+    @PreAuthorize("hasAnyRole('ADMIN','ROLE_GROUP')")
     @PostMapping("/mute/{id}")
     @PostMapping("/mute/{id}")
     public void mute(@PathVariable Long id) {
     public void mute(@PathVariable Long id) {
         teamService.mute(id);
         teamService.mute(id);
     }
     }
 
 
-    @PreAuthorize("hasRole('ADMIN')")
+    @PreAuthorize("hasAnyRole('ADMIN','ROLE_GROUP')")
     @PostMapping("/muteSolo")
     @PostMapping("/muteSolo")
     public void muteSolo(Long tid, String accid) {
     public void muteSolo(Long tid, String accid) {
         teamService.muteMember(tid, accid);
         teamService.muteMember(tid, accid);
     }
     }
 
 
-    @PreAuthorize("hasRole('ADMIN')")
+    @PreAuthorize("hasAnyRole('ADMIN','ROLE_GROUP')")
     @PostMapping("/cancelMuteSolo")
     @PostMapping("/cancelMuteSolo")
     public void cancelMuteSolo(Long tid, String accid) {
     public void cancelMuteSolo(Long tid, String accid) {
         teamService.cancelMuteMember(tid, accid);
         teamService.cancelMuteMember(tid, accid);
     }
     }
 
 
-    @PreAuthorize("hasRole('ADMIN')")
+    @PreAuthorize("hasAnyRole('ADMIN','ROLE_GROUP')")
     @PostMapping("/cancelMute/{id}")
     @PostMapping("/cancelMute/{id}")
     public void cancelMute(@PathVariable Long id) {
     public void cancelMute(@PathVariable Long id) {
         teamService.cancelMute(id);
         teamService.cancelMute(id);

+ 1 - 1
src/main/resources/application.yaml

@@ -149,7 +149,7 @@ aliyun:
   oss-end-point: oss-cn-shenzhen.aliyuncs.com
   oss-end-point: oss-cn-shenzhen.aliyuncs.com
   oss-bucket-name: raex-meta
   oss-bucket-name: raex-meta
   oss-domain: https://cdn.raex.vip
   oss-domain: https://cdn.raex.vip
-  sms-sign: 绿洲数字藏品中心
+  sms-sign: RAEX绿洲宇宙
   sms-code: SMS_228870098
   sms-code: SMS_228870098
   sell-out-code: SMS_246085423
   sell-out-code: SMS_246085423
   saas-sell-out-code: SMS_253195080
   saas-sell-out-code: SMS_253195080

+ 20 - 4
src/main/vue/src/router.js

@@ -1597,12 +1597,28 @@ const router = new Router({
                         title: '累计签到奖励领取记录',
                         title: '累计签到奖励领取记录',
                     },
                     },
                 },
                 },
+                {
+                    path: '/metaZoumaLightEdit',
+                    name: 'MetaZoumaLightEdit',
+                    component: () => import(/* webpackChunkName: "metaZoumaLightEdit" */ '@/views/MetaZoumaLightEdit.vue'),
+                    meta: {
+                        title: '走马灯编辑',
+                    },
+                },
+                {
+                    path: '/metaZoumaLightList',
+                    name: 'MetaZoumaLightList',
+                    component: () => import(/* webpackChunkName: "metaZoumaLightList" */ '@/views/MetaZoumaLightList.vue'),
+                    meta: {
+                        title: '走马灯',
+                    },
+                },
                 {
                 {
                     path: '/metaSwitchEdit',
                     path: '/metaSwitchEdit',
                     name: 'MetaSwitchEdit',
                     name: 'MetaSwitchEdit',
                     component: () => import(/* webpackChunkName: "metaSwitchEdit" */ '@/views/MetaSwitchEdit.vue'),
                     component: () => import(/* webpackChunkName: "metaSwitchEdit" */ '@/views/MetaSwitchEdit.vue'),
                     meta: {
                     meta: {
-                       title: '元宇宙开关配置编辑',
+                        title: '元宇宙开关配置编辑',
                     },
                     },
                 },
                 },
                 {
                 {
@@ -1610,9 +1626,9 @@ const router = new Router({
                     name: 'MetaSwitchList',
                     name: 'MetaSwitchList',
                     component: () => import(/* webpackChunkName: "metaSwitchList" */ '@/views/MetaSwitchList.vue'),
                     component: () => import(/* webpackChunkName: "metaSwitchList" */ '@/views/MetaSwitchList.vue'),
                     meta: {
                     meta: {
-                       title: '元宇宙开关配置',
+                        title: '元宇宙开关配置',
                     },
                     },
-               }
+                }
                 /**INSERT_LOCATION**/
                 /**INSERT_LOCATION**/
             ]
             ]
         },
         },
@@ -1672,4 +1688,4 @@ router.beforeEach((to, from, next) => {
     }
     }
 });
 });
 
 
-export default router;
+export default router;

+ 134 - 128
src/main/vue/src/views/MetaEmailEdit.vue

@@ -1,133 +1,139 @@
 <template>
 <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="title" label="邮件标题">
-                                    <el-input v-model="formData.title"></el-input>
-                        </el-form-item>
-                        <el-form-item prop="auther" label="邮件作者">
-                                    <el-input v-model="formData.auther"></el-input>
-                        </el-form-item>
-                        <el-form-item prop="description" label="邮件内容" style="width: calc(100vw - 450px)">
-                        <el-input
-                            v-model="formData.description"
-                            type="textarea"
-                            :autosize="{ minRows: 3, maxRows: 20 }"
-                            placeholder="请输入邮件内容"
-                        >
-                        </el-input>
-                    </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>
+	<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="title" label="邮件标题">
+						<el-input v-model="formData.title"> </el-input>
+					</el-form-item>
+					<el-form-item prop="author" label="邮件作者">
+						<el-input v-model="formData.author"> </el-input>
+					</el-form-item>
+					<el-form-item prop="description" label="邮件内容" style="width: calc(100vw - 450px)">
+						<el-input
+							v-model="formData.description"
+							type="textarea"
+							:autosize="{ minRows: 3, maxRows: 20 }"
+							placeholder="请输入邮件内容"
+						>
+						</el-input>
+					</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>
 </template>
 <script>
 <script>
-    export default {
-        name: 'MetaEmailEdit',
-        created() {
-            if (this.$route.query.id) {
-                this.$http
-                    .get('metaEmail/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: {
-                },
-                rules: {
-                    title: [
-                    {
-                        required: true,
-                        message: '请输入邮件标题',
-                        trigger: 'blur'
-                    }
-                ],
-                    auther: [
-                    {
-                        required: true,
-                        message: '请输入邮件作者',
-                        trigger: 'blur'
-                    }
-                ],
-                    description: [
-                    {
-                        required: true,
-                        message: '请输入邮件内容',
-                        trigger: 'blur'
-                    }
-                ]
-                },
-            }
-        },
-        methods: {
-            onSave() {
-                this.$refs.form.validate((valid) => {
-                    if (valid) {
-                        this.submit();
-                    } else {
-                        return false;
-                    }
-                });
-            },
-            submit() {
-                let data = {...this.formData};
+export default {
+	name: 'MetaEmailEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaEmail/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: {},
+			rules: {
+				title: [
+					{
+						required: true,
+						message: '请输入邮件标题',
+						trigger: 'blur'
+					}
+				],
+				author: [
+					{
+						required: true,
+						message: '请输入邮件作者',
+						trigger: 'blur'
+					}
+				],
+				description: [
+					{
+						required: true,
+						message: '请输入邮件内容',
+						trigger: 'blur'
+					}
+				]
+			}
+		};
+	},
+	methods: {
+		onSave() {
+			this.$refs.form.validate(valid => {
+				if (valid) {
+					this.submit();
+				} else {
+					return false;
+				}
+			});
+		},
+		submit() {
+			let data = { ...this.formData };
 
 
-                this.saving = true;
-                this.$http
-                    .post('/metaEmail/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(`/metaEmail/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 || '删除失败');
-                    }
-                })
-            },
-        }
-    }
+			this.saving = true;
+			this.$http
+				.post('/metaEmail/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(`/metaEmail/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>
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+
+</style>

+ 178 - 160
src/main/vue/src/views/MetaEmailList.vue

@@ -1,169 +1,187 @@
 <template>
 <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="title" label="邮件标题"
->
-                    </el-table-column>
-                    <el-table-column prop="auther" label="邮件作者"
->
-                    </el-table-column>
-                    <el-table-column prop="description" label="邮件内容"
->
-                    </el-table-column>
-            <el-table-column
-                    label="操作"
-                    align="center"
-                    fixed="right"
-                    width="150">
-                <template slot-scope="{row}">
-                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
-                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+	<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" align="center" label="ID" width="100"> </el-table-column>
+			<el-table-column prop="title" align="center" label="邮件标题" width="200"> </el-table-column>
+			<el-table-column prop="author" align="center" label="邮件作者" width="100"> </el-table-column>
+			<el-table-column prop="description" align="center" label="邮件内容" width="500"> </el-table-column>
+            <el-table-column prop="publish" align="center" label="是否发布" width="80">
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.publish ? '' : 'info'"> {{ row.publish }} </el-tag>
                 </template>
                 </template>
             </el-table-column>
             </el-table-column>
-        </el-table>
-        <div class="pagination-wrapper">
-            <!-- <div class="multiple-mode-wrapper">
-                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
-                <el-button-group v-else>
-                    <el-button @click="operation1">批量操作1</el-button>
-                    <el-button @click="operation2">批量操作2</el-button>
-                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
-                </el-button-group>
-            </div> -->
-            <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>
-
-    </div>
+			<el-table-column label="操作" align="center" fixed="right" width="300">
+				<template slot-scope="{ row }">
+					<el-button @click="editRow(row)" type="primary" size="mini" plain v-if="row && !row.publish">
+						编辑
+					</el-button>
+					<el-button @click="publish(row)" type="primary" size="mini" plain v-if="row && !row.publish"> 发布 </el-button>
+					<el-button @click="deleteRow(row)" type="danger" size="mini" plain v-if="row && !row.publish">
+						删除
+					</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>
+	</div>
 </template>
 </template>
 <script>
 <script>
-    import { mapState } from "vuex";
-    import pageableTable from "@/mixins/pageableTable";
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
 
 
-    export default {
-        name: 'MetaEmailList',
-        mixins: [pageableTable],
-        data() {
-            return {
-                multipleMode: false,
-                search: "",
-                url: "/metaEmail/all",
-                downloading: false,
-            }
-        },
-        computed: {
-            selection() {
-                return this.$refs.table.selection.map(i => i.id);
-            }
-        },
-        methods: {
-            beforeGetData() {
-                return { search: this.search, query: { del: false } };
-            },
-            toggleMultipleMode(multipleMode) {
-                this.multipleMode = multipleMode;
-                if (!multipleMode) {
-                    this.$refs.table.clearSelection();
-                }
-            },
-            addRow() {
-                this.$router.push({
-                    path: "/metaEmailEdit",
-                    query: {
-                        ...this.$route.query
-                    }
-                });
-            },
-            editRow(row) {
-                this.$router.push({
-                    path: "/metaEmailEdit",
-                    query: {
-                    id: row.id
-                    }
-                });
-            },
-            download() {
-                this.downloading = true;
-                this.$axios
-                    .get("/metaEmail/excel", { 
-                        responseType: "blob",
-                        params: { size: 10000 }
-                    })
-                    .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(`/metaEmail/del/${row.id}`)
-                }).then(() => {
-                    this.$message.success('删除成功');
-                    this.getData();
-                }).catch(e => {
-                    if (e !== 'cancel') {
-                        this.$message.error(e.error);
-                    }
-                })
-            },
-        }
-    }
+export default {
+	name: 'MetaEmailList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			multipleMode: false,
+			search: '',
+			url: '/metaEmail/all',
+			downloading: false
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		beforeGetData() {
+			return { search: this.search, query: { del: false } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		addRow() {
+			this.$router.push({
+				path: '/metaEmailEdit',
+				query: {
+					...this.$route.query
+				}
+			});
+		},
+		editRow(row) {
+			this.$router.push({
+				path: '/metaEmailEdit',
+				query: {
+					id: row.id
+				}
+			});
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaEmail/excel', {
+					responseType: 'blob',
+					params: { size: 10000 }
+				})
+				.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);
+				});
+		},
+		deleteRow(row) {
+			this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaEmail/del/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('删除成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		},
+		publish(row) {
+			this.$alert('邮件发布之后不能编辑和删除,请确定是否发布邮件!', '提示', { type: 'info' })
+				.then(() => {
+					return this.$http.post(`/metaEmail/${row.id}/publish`);
+				})
+				.then(() => {
+					this.$message.success('发布成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		}
+	}
+};
 </script>
 </script>
 <style lang="less" scoped>
 <style lang="less" scoped>
+
 </style>
 </style>

+ 123 - 0
src/main/vue/src/views/MetaZoumaLightEdit.vue

@@ -0,0 +1,123 @@
+<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="94px"
+					label-position="right"
+					size="small"
+					style="max-width: 500px"
+				>
+					<el-form-item prop="description" label="走马灯详情" style="width: calc(100vw - 450px)">
+						<el-input
+							v-model="formData.description"
+							type="textarea"
+							:autosize="{ minRows: 3, maxRows: 20 }"
+							placeholder="请输入走马灯详情"
+						>
+						</el-input>
+					</el-form-item>
+					<el-form-item prop="publish" label="是否发布">
+						<el-switch v-model="formData.publish"> </el-switch>
+					</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: 'MetaZoumaLightEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaZoumaLight/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: {},
+			rules: {
+				description: [
+					{
+						required: true,
+						message: '请输入走马灯详情',
+						trigger: 'blur'
+					}
+				]
+			}
+		};
+	},
+	methods: {
+		onSave() {
+			this.$refs.form.validate(valid => {
+				if (valid) {
+					this.submit();
+				} else {
+					return false;
+				}
+			});
+		},
+		submit() {
+			let data = { ...this.formData };
+
+			this.saving = true;
+			this.$http
+				.post('/metaZoumaLight/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(`/metaZoumaLight/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>

+ 182 - 0
src/main/vue/src/views/MetaZoumaLightList.vue

@@ -0,0 +1,182 @@
+<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="description" label="走马灯详情"> </el-table-column>
+            <el-table-column prop="publish" align="center" label="是否发布">
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.publish ? '' : 'info'"> {{ row.publish }} </el-tag>
+                </template>
+            </el-table-column>
+			<el-table-column label="操作" align="center" fixed="right" width="150">
+				<template slot-scope="{ row }">
+					<el-button @click="editRow(row)" type="primary" size="mini" plain> 编辑 </el-button>
+					<el-button @click="deleteRow(row)" type="danger" size="mini" plain> 删除 </el-button>
+				</template>
+			</el-table-column>
+		</el-table>
+		<div class="pagination-wrapper">
+			<!-- <div class="multiple-mode-wrapper"> 
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)"> 批量编辑 </el-button>
+                <el-button-group v-else> 
+                    <el-button @click="operation1"> 批量操作1 </el-button>
+                    <el-button @click="operation2"> 批量操作2 </el-button>
+                    <el-button @click="toggleMultipleMode(false)"> 取消 </el-button>
+                </el-button-group>
+            </div> -->
+			<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>
+	</div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+	name: 'MetaZoumaLightList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			multipleMode: false,
+			search: '',
+			url: '/metaZoumaLight/all',
+			downloading: false
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		beforeGetData() {
+			return { search: this.search, query: { del: false } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		addRow() {
+			this.$router.push({
+				path: '/metaZoumaLightEdit',
+				query: {
+					...this.$route.query
+				}
+			});
+		},
+		editRow(row) {
+			this.$router.push({
+				path: '/metaZoumaLightEdit',
+				query: {
+					id: row.id
+				}
+			});
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaZoumaLight/excel', {
+					responseType: 'blob',
+					params: { size: 10000 }
+				})
+				.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(`/metaZoumaLight/del/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('删除成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		}
+	}
+};
+</script>
+<style lang="less" scoped>
+
+</style>

+ 5 - 3
src/main/vue/src/widgets/MonthWidget.vue

@@ -17,10 +17,11 @@
         </template>
         </template>
         <div class="box-content">
         <div class="box-content">
             <div class="box">
             <div class="box">
-                <div class="text1">官方销售额/二手市场</div>
+                <div class="text1">官方销售额/二手市场/充值金额</div>
                 <div class="text2">
                 <div class="text2">
                     <span v-html="getNum(order.official, true)"></span>/
                     <span v-html="getNum(order.official, true)"></span>/
-                    <span v-html="getNum(order.transfer, true)"></span>
+                    <span v-html="getNum(order.transfer, true)"></span>/
+                    <span v-html="getNum(order.recharged, true)"></span>
                 </div>
                 </div>
             </div>
             </div>
             <div class="box">
             <div class="box">
@@ -46,7 +47,8 @@ export default {
             user: 0,
             user: 0,
             order: {
             order: {
                 official: 0,
                 official: 0,
-                transfer: 0
+                transfer: 0,
+                recharged: 0
             }
             }
         };
         };
     },
     },

+ 14 - 6
src/main/vue/src/widgets/PieChartWidget.vue

@@ -17,9 +17,10 @@
         </template>
         </template>
         <div class="box-content" ref="box">
         <div class="box-content" ref="box">
             <div class="box">
             <div class="box">
-                <div class="text1">官方销售额/二手市场</div>
+                <div class="text1">官方销售额/二手市场/充值金额</div>
                 <div class="text2">
                 <div class="text2">
                     <span v-html="getNum(official, true)"></span>/ <span v-html="getNum(transfer, true)"></span>
                     <span v-html="getNum(official, true)"></span>/ <span v-html="getNum(transfer, true)"></span>
+                    / <span v-html="getNum(recharged, true)"></span>
                 </div>
                 </div>
             </div>
             </div>
             <div class="box">
             <div class="box">
@@ -35,7 +36,7 @@
 <script>
 <script>
 import WidgetCard from './WidgetCard';
 import WidgetCard from './WidgetCard';
 import VueCharts from 'vue-chartjs';
 import VueCharts from 'vue-chartjs';
-import { format } from 'date-fns';
+import {format} from 'date-fns';
 import acc from '../mixins/acc';
 import acc from '../mixins/acc';
 import addDays from 'date-fns/esm/addDays';
 import addDays from 'date-fns/esm/addDays';
 
 
@@ -50,6 +51,7 @@ export default {
             },
             },
             official: 0,
             official: 0,
             transfer: 0,
             transfer: 0,
+            recharged: 0,
             officialNum: 0,
             officialNum: 0,
             transferNum: 0,
             transferNum: 0,
             value: '',
             value: '',
@@ -97,7 +99,7 @@ export default {
                             this.config = {
                             this.config = {
                                 type: 'doughnut',
                                 type: 'doughnut',
                                 data: {
                                 data: {
-                                    labels: ['官方销售额', '二手市场销售额'],
+                                    labels: ['官方销售额', '二手市场销售额', '充值金额'],
                                     datasets: []
                                     datasets: []
                                 },
                                 },
                                 options: {
                                 options: {
@@ -116,11 +118,12 @@ export default {
             this.transferNum = this.numInfo.transfer ? this.numInfo.transfer[value] || 0 : 0;
             this.transferNum = this.numInfo.transfer ? this.numInfo.transfer[value] || 0 : 0;
             this.official = this.priceInfo.official ? this.priceInfo.official[value] || 0 : 0;
             this.official = this.priceInfo.official ? this.priceInfo.official[value] || 0 : 0;
             this.transfer = this.priceInfo.transfer ? this.priceInfo.transfer[value] || 0 : 0;
             this.transfer = this.priceInfo.transfer ? this.priceInfo.transfer[value] || 0 : 0;
+            this.recharged = this.priceInfo.recharged ? this.priceInfo.recharged[value] || 0 : 0;
             this.config.data.datasets = [
             this.config.data.datasets = [
                 {
                 {
                     title: '销售额',
                     title: '销售额',
-                    backgroundColor: ['#FEB30E', '#FF7970'],
-                    data: [this.official, this.transfer]
+                    backgroundColor: ['#FEB30E', '#FF7970', '#0000FF'],
+                    data: [this.official, this.transfer, this.recharged]
                 }
                 }
             ];
             ];
             this.myChart.update();
             this.myChart.update();
@@ -145,6 +148,7 @@ export default {
     align-self: stretch;
     align-self: stretch;
     padding: 30px;
     padding: 30px;
 }
 }
+
 .box {
 .box {
     padding: 0 20px;
     padding: 0 20px;
     height: 125px;
     height: 125px;
@@ -156,6 +160,7 @@ export default {
     justify-content: center;
     justify-content: center;
     min-width: 153px;
     min-width: 153px;
     box-sizing: border-box;
     box-sizing: border-box;
+
     .text1 {
     .text1 {
         font-size: 14px;
         font-size: 14px;
         font-weight: bold;
         font-weight: bold;
@@ -163,6 +168,7 @@ export default {
         line-height: 20px;
         line-height: 20px;
         white-space: nowrap;
         white-space: nowrap;
     }
     }
+
     .text2 {
     .text2 {
         color: #feb30e;
         color: #feb30e;
         font-size: 22px;
         font-size: 22px;
@@ -170,7 +176,8 @@ export default {
         line-height: 29px;
         line-height: 29px;
         margin-top: 2px;
         margin-top: 2px;
         white-space: nowrap;
         white-space: nowrap;
-        /deep/small {
+
+        /deep/ small {
             font-size: 12px;
             font-size: 12px;
         }
         }
     }
     }
@@ -181,6 +188,7 @@ export default {
         }
         }
     }
     }
 }
 }
+
 .header {
 .header {
     display: flex;
     display: flex;
     justify-content: space-between;
     justify-content: space-between;

+ 9 - 3
src/main/vue/src/widgets/PriceWidget.vue

@@ -2,14 +2,18 @@
     <widget-card :bodyStyle="bodyStyle">
     <widget-card :bodyStyle="bodyStyle">
         <i class="fa-fw fas fa-shopping-basket fa-3x" style="color: #40c9c6;"></i>
         <i class="fa-fw fas fa-shopping-basket fa-3x" style="color: #40c9c6;"></i>
         <div class="info">
         <div class="info">
-            <div class="text">官方交易额/二手市场(万元)</div>
-            <div class="num">{{ getNum(info.officialPrice || 0) }}/{{ getNum(info.transferPrice || 0) }}</div>
+            <div class="text">官方交易额/二手市场/充值金额(万元)</div>
+            <div class="num">{{ getNum(info.officialPrice || 0) }}/
+                {{ getNum(info.transferPrice || 0) }}/
+                {{ getNum(info.rechargePrice || 0) }}
+            </div>
         </div>
         </div>
     </widget-card>
     </widget-card>
 </template>
 </template>
 <script>
 <script>
 import WidgetCard from './WidgetCard';
 import WidgetCard from './WidgetCard';
 import acc from '../mixins/acc';
 import acc from '../mixins/acc';
+
 export default {
 export default {
     props: {
     props: {
         info: {
         info: {
@@ -21,7 +25,7 @@ export default {
     },
     },
     computed: {
     computed: {
         total() {
         total() {
-            return this.accAdd(this.info.officialPrice || 0, this.info.transferPrice || 0);
+            return this.accAdd(this.info.officialPrice || 0, this.info.transferPrice || 0, this.info.rechargePrice || 0);
         }
         }
     },
     },
     mixins: [acc],
     mixins: [acc],
@@ -42,11 +46,13 @@ export default {
 .info {
 .info {
     flex-grow: 1;
     flex-grow: 1;
     text-align: right;
     text-align: right;
+
     .text {
     .text {
         color: #999;
         color: #999;
         font-size: 16px;
         font-size: 16px;
         margin-bottom: 12px;
         margin-bottom: 12px;
     }
     }
+
     .num {
     .num {
         font-size: 20px;
         font-size: 20px;
         color: #333;
         color: #333;