Browse Source

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

wangqifan 3 years ago
parent
commit
5fc07de75f
79 changed files with 8242 additions and 6360 deletions
  1. 2 0
      src/main/java/com/izouma/nineth/config/Constants.java
  2. 41 0
      src/main/java/com/izouma/nineth/domain/MetaBoatPosition.java
  3. 4 0
      src/main/java/com/izouma/nineth/domain/MetaSpatialInfo.java
  4. 48 0
      src/main/java/com/izouma/nineth/domain/MetaSpatialWharf.java
  5. 29 0
      src/main/java/com/izouma/nineth/domain/MetaVisitor.java
  6. 9 0
      src/main/java/com/izouma/nineth/domain/PublicScreenChat.java
  7. 17 0
      src/main/java/com/izouma/nineth/dto/MetaBoatDTO.java
  8. 21 0
      src/main/java/com/izouma/nineth/enums/MetaIsLandTypeEnum.java
  9. 5 1
      src/main/java/com/izouma/nineth/repo/AssetRepo.java
  10. 3 0
      src/main/java/com/izouma/nineth/repo/MetaAccessoriesPurchaseRecordRepo.java
  11. 21 0
      src/main/java/com/izouma/nineth/repo/MetaBoatPositionRepo.java
  12. 5 0
      src/main/java/com/izouma/nineth/repo/MetaSpatialInfoRepo.java
  13. 34 0
      src/main/java/com/izouma/nineth/repo/MetaSpatialWharfRepo.java
  14. 22 0
      src/main/java/com/izouma/nineth/repo/MetaVisitorRepo.java
  15. 8 0
      src/main/java/com/izouma/nineth/repo/PublicScreenChatRepo.java
  16. 27 11
      src/main/java/com/izouma/nineth/service/MetaAccessoriesService.java
  17. 74 0
      src/main/java/com/izouma/nineth/service/MetaBoatPositionService.java
  18. 2 0
      src/main/java/com/izouma/nineth/service/MetaGameBoxPointsService.java
  19. 112 0
      src/main/java/com/izouma/nineth/service/MetaSpatialWharfService.java
  20. 20 0
      src/main/java/com/izouma/nineth/service/MetaVisitorService.java
  21. 16 0
      src/main/java/com/izouma/nineth/utils/MathUtils.java
  22. 1 0
      src/main/java/com/izouma/nineth/utils/excel/ExcelUtils.java
  23. 42 0
      src/main/java/com/izouma/nineth/utils/excel/MetaIsLandTypeEnumConverter.java
  24. 2 5
      src/main/java/com/izouma/nineth/web/MetaAccessoriesController.java
  25. 72 0
      src/main/java/com/izouma/nineth/web/MetaBoatPositionController.java
  26. 11 0
      src/main/java/com/izouma/nineth/web/MetaSpatialInfoController.java
  27. 82 0
      src/main/java/com/izouma/nineth/web/MetaSpatialWharfController.java
  28. 46 0
      src/main/java/com/izouma/nineth/web/MetaVisitorController.java
  29. 8 0
      src/main/java/com/izouma/nineth/web/PublicScreenChatController.java
  30. 20 0
      src/main/java/com/izouma/nineth/web/UserDetailController.java
  31. 1 0
      src/main/resources/genjson/MetaBoatPosition.json
  32. 1 0
      src/main/resources/genjson/MetaSpatialWharf.json
  33. 1 0
      src/main/resources/genjson/MetaVisitor.json
  34. 265 109
      src/main/resources/static/Agreement.html
  35. 42 1
      src/main/vue/src/router.js
  36. 165 0
      src/main/vue/src/views/LivePublicScreenChatList.vue
  37. 175 175
      src/main/vue/src/views/MetaAccessoriesEdit.vue
  38. 173 173
      src/main/vue/src/views/MetaAccessoriesList.vue
  39. 125 125
      src/main/vue/src/views/MetaAdvertRecordEdit.vue
  40. 156 156
      src/main/vue/src/views/MetaAdvertRecordList.vue
  41. 193 0
      src/main/vue/src/views/MetaBoatPositionEdit.vue
  42. 182 0
      src/main/vue/src/views/MetaBoatPositionList.vue
  43. 89 88
      src/main/vue/src/views/MetaBonusSceneList.vue
  44. 231 231
      src/main/vue/src/views/MetaDestroyActivityEdit.vue
  45. 188 188
      src/main/vue/src/views/MetaDestroyActivityList.vue
  46. 138 136
      src/main/vue/src/views/MetaDestroyRecordList.vue
  47. 102 102
      src/main/vue/src/views/MetaGameBoxPointsList.vue
  48. 487 471
      src/main/vue/src/views/MetaGameCopyEdit.vue
  49. 221 219
      src/main/vue/src/views/MetaGameCopyList.vue
  50. 188 188
      src/main/vue/src/views/MetaGameProcessList.vue
  51. 144 144
      src/main/vue/src/views/MetaGameStageAwardEdit.vue
  52. 178 178
      src/main/vue/src/views/MetaGameStageAwardList.vue
  53. 125 125
      src/main/vue/src/views/MetaItemEdit.vue
  54. 170 170
      src/main/vue/src/views/MetaItemList.vue
  55. 120 120
      src/main/vue/src/views/MetaMMOLoginInfoList.vue
  56. 181 177
      src/main/vue/src/views/MetaPlayerRoleClassifyEdit.vue
  57. 164 164
      src/main/vue/src/views/MetaPlayerRoleClassifyList.vue
  58. 154 153
      src/main/vue/src/views/MetaPlayerWearEdit.vue
  59. 175 174
      src/main/vue/src/views/MetaPlayerWearList.vue
  60. 113 113
      src/main/vue/src/views/MetaResourceVersionEdit.vue
  61. 159 159
      src/main/vue/src/views/MetaResourceVersionList.vue
  62. 106 106
      src/main/vue/src/views/MetaShowRoomAssetList.vue
  63. 22 0
      src/main/vue/src/views/MetaSpatialInfoEdit.vue
  64. 189 188
      src/main/vue/src/views/MetaSpatialInfoList.vue
  65. 139 0
      src/main/vue/src/views/MetaSpatialWharfList.vue
  66. 136 136
      src/main/vue/src/views/MetaTaskActivityEdit.vue
  67. 176 176
      src/main/vue/src/views/MetaTaskActivityList.vue
  68. 265 265
      src/main/vue/src/views/MetaTaskEdit.vue
  69. 238 238
      src/main/vue/src/views/MetaTaskList.vue
  70. 145 145
      src/main/vue/src/views/MetaTaskToUserList.vue
  71. 101 100
      src/main/vue/src/views/MetaUserEdit.vue
  72. 195 195
      src/main/vue/src/views/MetaUserGoldList.vue
  73. 150 150
      src/main/vue/src/views/MetaUserGoldRecordList.vue
  74. 156 155
      src/main/vue/src/views/MetaUserList.vue
  75. 118 118
      src/main/vue/src/views/MetaUserTaskProgressList.vue
  76. 166 0
      src/main/vue/src/views/MetaVisitorList.vue
  77. 144 144
      src/main/vue/src/views/MetaZombieEdit.vue
  78. 185 187
      src/main/vue/src/views/MetaZombieList.vue
  79. 1 1
      src/main/vue/src/views/PublicScreenChatList.vue

+ 2 - 0
src/main/java/com/izouma/nineth/config/Constants.java

@@ -63,11 +63,13 @@ public interface Constants {
         String SR  = "SR";
         String U   = "U";
         String R   = "R";
+        String UR  = "UR";
 
         String SSR_LIKE = "%SSR #%";
         String SR_LIKE  = "%SR #%";
         String U_LIKE   = "%U #%";
         String R_LIKE   = "%R #%";
+        String UR_LIKE  = "%UR #%";
 
         String ACTIVITY_RANK_ID = "activity_rank_id";
     }

+ 41 - 0
src/main/java/com/izouma/nineth/domain/MetaBoatPosition.java

@@ -0,0 +1,41 @@
+package com.izouma.nineth.domain;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.izouma.nineth.converter.CoordinateConverter;
+import com.izouma.nineth.dto.CoordinateDTO;
+import com.izouma.nineth.enums.MetaIsLandTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@ApiModel("元宇宙空间船位")
+public class MetaBoatPosition extends BaseEntity {
+
+    @ApiModelProperty("岛屿类型")
+    @ExcelProperty("岛屿类型")
+    @Enumerated(EnumType.STRING)
+    private MetaIsLandTypeEnum type;
+
+    @ApiModelProperty("位置信息")
+    @ExcelProperty("位置信息")
+    @Convert(converter = CoordinateConverter.class)
+    private CoordinateDTO boatPos;
+
+    @ApiModelProperty("旋转值")
+    @ExcelProperty("旋转值")
+    @Convert(converter = CoordinateConverter.class)
+    private CoordinateDTO boatRot;
+
+    @Transient
+    @ExcelIgnore
+    private MetaSpatialWharf boatInfo;
+}

+ 4 - 0
src/main/java/com/izouma/nineth/domain/MetaSpatialInfo.java

@@ -56,4 +56,8 @@ public class MetaSpatialInfo extends BaseEntity {
     @Searchable
     private String hcTxHash;
 
+    @ApiModelProperty("类型")
+    @ExcelProperty("类型")
+    private int type;
+
 }

+ 48 - 0
src/main/java/com/izouma/nineth/domain/MetaSpatialWharf.java

@@ -0,0 +1,48 @@
+package com.izouma.nineth.domain;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+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;
+import javax.persistence.Transient;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@ApiModel("元宇宙空间码头列表")
+public class MetaSpatialWharf extends BaseEntity {
+
+    @ApiModelProperty("岛屿id 对应元宇宙空间id")
+    @ExcelProperty("岛屿id 对应元宇宙空间id")
+    private Long isLandId;
+
+    @ApiModelProperty("船只id 对应NFT资产id")
+    @ExcelProperty("船只id 对应NFT资产id")
+    private Long boatId;
+
+    @ApiModelProperty("船只图片 NFT图片")
+    @ExcelProperty("船只图片 NFT图片")
+    private String boatImg;
+
+    @ApiModelProperty("所属用户")
+    @ExcelProperty("所属用户")
+    private Long userId;
+
+    @ApiModelProperty("船只类型 NFT稀有度")
+    @ExcelProperty("船只类型 NFT稀有度")
+    private String boatType;
+
+    @ApiModelProperty("船位id")
+    @ExcelProperty("船位id")
+    private Long metaBoatPositionId;
+
+    @Transient
+    @ExcelIgnore
+    private boolean meUse;
+}

+ 29 - 0
src/main/java/com/izouma/nineth/domain/MetaVisitor.java

@@ -0,0 +1,29 @@
+package com.izouma.nineth.domain;
+
+import com.izouma.nineth.annotations.Searchable;
+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 MetaVisitor extends BaseEntity {
+
+    @ApiModelProperty("游客头像")
+    private String avatar;
+
+    @ApiModelProperty("游客昵称")
+    @Searchable
+    private String nickname;
+
+    @ApiModelProperty("是否禁言")
+    private boolean taboo;
+
+}

+ 9 - 0
src/main/java/com/izouma/nineth/domain/PublicScreenChat.java

@@ -1,5 +1,6 @@
 package com.izouma.nineth.domain;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.izouma.nineth.annotations.Searchable;
 import io.swagger.annotations.ApiModel;
@@ -57,6 +58,14 @@ public class PublicScreenChat extends BaseEntity {
     @ExcelProperty("消息是否合法")
     private boolean illegal;
 
+    @ApiModelProperty("1:正常,2:待撤回,3:已撤回")
+    @ExcelIgnore
+    private int recall;
+
+    @ApiModelProperty("类型 1:直播 2:元宇宙聊天")
+    @ExcelIgnore
+    private int type;
+
     @Transient
     private boolean myself;
 }

+ 17 - 0
src/main/java/com/izouma/nineth/dto/MetaBoatDTO.java

@@ -0,0 +1,17 @@
+package com.izouma.nineth.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MetaBoatDTO {
+
+    private Long boatId;
+
+    private String boatImg;
+
+    private String boatType;
+}

+ 21 - 0
src/main/java/com/izouma/nineth/enums/MetaIsLandTypeEnum.java

@@ -0,0 +1,21 @@
+package com.izouma.nineth.enums;
+
+
+public enum MetaIsLandTypeEnum {
+
+    TEN_THOUSAND("10000m²空间岛"),
+
+    SIX_THOUSAND("60000m²空间岛"),
+
+    NINE_THOUSAND("90000m²空间岛");
+
+    private final String description;
+
+    MetaIsLandTypeEnum(String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 5 - 1
src/main/java/com/izouma/nineth/repo/AssetRepo.java

@@ -10,7 +10,6 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
-import javax.transaction.Status;
 import javax.transaction.Transactional;
 import java.time.LocalDateTime;
 import java.util.*;
@@ -21,6 +20,8 @@ public interface AssetRepo extends JpaRepository<Asset, Long>, JpaSpecificationE
     @Transactional
     void softDelete(Long id);
 
+    Asset findByIdAndUserIdAndDel(Long id, Long userId, boolean del);
+
     long countByIpfsUrlAndStatusNot(String ipfsUrl, AssetStatus status);
 
     List<Asset> findByCollectionId(Long collectionId);
@@ -135,4 +136,7 @@ public interface AssetRepo extends JpaRepository<Asset, Long>, JpaSpecificationE
 
     @Query("select count(id) from Asset where name like ?1 and status = 'NORMAL' and ownerId <> 1435297")
     Long countNameLikeNotDestroyed(String name);
+
+    @Query(value = "select * from asset where name like ?1 and status in ?2 and id not in ?3 and del = false", nativeQuery = true)
+    List<Asset> findAllBoats(String name, List<AssetStatus> status, List<Long> boatIds);
 }

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

@@ -4,9 +4,12 @@ import com.izouma.nineth.domain.MetaAccessoriesPurchaseRecord;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 
+import java.util.List;
+
 
 public interface MetaAccessoriesPurchaseRecordRepo extends JpaRepository<MetaAccessoriesPurchaseRecord, Long>, JpaSpecificationExecutor<MetaAccessoriesPurchaseRecord> {
 
     MetaAccessoriesPurchaseRecord findByUserIdAndMetaAccessoriesId(Long userId, Long metaAccessories);
 
+    List<MetaAccessoriesPurchaseRecord> findByUserIdAndMetaAccessoriesIdIn(Long userId, List<Long> metaAccessories);
 }

+ 21 - 0
src/main/java/com/izouma/nineth/repo/MetaBoatPositionRepo.java

@@ -0,0 +1,21 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.domain.MetaBoatPosition;
+import com.izouma.nineth.enums.MetaIsLandTypeEnum;
+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;
+import java.util.List;
+
+public interface MetaBoatPositionRepo extends JpaRepository<MetaBoatPosition, Long>, JpaSpecificationExecutor<MetaBoatPosition> {
+
+    @Query("update MetaBoatPosition t set t.del = true where t.id = ?1")
+    @Modifying
+    @Transactional
+    void softDelete(Long id);
+
+    List<MetaBoatPosition> findAllByTypeAndDel(MetaIsLandTypeEnum type, boolean del);
+}

+ 5 - 0
src/main/java/com/izouma/nineth/repo/MetaSpatialInfoRepo.java

@@ -28,4 +28,9 @@ public interface MetaSpatialInfoRepo extends JpaRepository<MetaSpatialInfo, Long
 
     MetaSpatialInfo findByHcTxHashAndDel(String hcTxHash, boolean del);
 
+    @Query(value = "select * from meta_spatial_info where type = ?1 and del = false and user_id <> ?2", nativeQuery = true)
+    List<MetaSpatialInfo> findByTypeAndUserIdNot(int type, Long userId);
+
+    MetaSpatialInfo findByIdAndDel(Long id, boolean del);
+
 }

+ 34 - 0
src/main/java/com/izouma/nineth/repo/MetaSpatialWharfRepo.java

@@ -0,0 +1,34 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.domain.MetaSpatialWharf;
+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;
+import java.util.List;
+
+public interface MetaSpatialWharfRepo extends JpaRepository<MetaSpatialWharf, Long>, JpaSpecificationExecutor<MetaSpatialWharf> {
+
+    MetaSpatialWharf findByBoatIdAndUserIdAndDel(Long boatId, Long userId, boolean del);
+
+    MetaSpatialWharf findByMetaBoatPositionIdAndDel(Long metaBoatPositionId, boolean del);
+
+    @Query(value = "delete from meta_spatial_wharf where boat_id = ?1", nativeQuery = true)
+    @Modifying
+    @Transactional
+    int back(Long boatId);
+
+    @Query(value = "delete from meta_spatial_wharf where user_id = ?1", nativeQuery = true)
+    @Modifying
+    @Transactional
+    int backAll(Long userId);
+
+    MetaSpatialWharf findByBoatIdAndDel(Long boatId, boolean del);
+
+    @Query(value = "select id from meta_spatial_wharf where user_id = ?1 and del = false", nativeQuery = true)
+    List<Long> findParkingBoatIds(Long userId);
+
+    MetaSpatialWharf findAllByIsLandIdAndMetaBoatPositionIdAndDel(Long isLandId, Long metaPositionId, boolean del);
+}

+ 22 - 0
src/main/java/com/izouma/nineth/repo/MetaVisitorRepo.java

@@ -0,0 +1,22 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.domain.MetaVisitor;
+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 MetaVisitorRepo extends JpaRepository<MetaVisitor, Long>, JpaSpecificationExecutor<MetaVisitor> {
+
+    @Query("update MetaVisitor t set t.taboo = true where t.id = ?1 and t.del = false")
+    @Modifying
+    @Transactional
+    void taboo(Long id);
+
+    @Query("update MetaVisitor t set t.taboo = false where t.id = ?1 and t.del = false")
+    @Modifying
+    @Transactional
+    void cancelTaboo(Long id);
+}

+ 8 - 0
src/main/java/com/izouma/nineth/repo/PublicScreenChatRepo.java

@@ -3,7 +3,15 @@ package com.izouma.nineth.repo;
 import com.izouma.nineth.domain.PublicScreenChat;
 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 PublicScreenChatRepo extends JpaRepository<PublicScreenChat, Long>, JpaSpecificationExecutor<PublicScreenChat> {
 
+    @Query("update PublicScreenChat t set t.recall = 2 where t.id = ?1")
+    @Modifying
+    @Transactional
+    void recall(Long id);
 }

+ 27 - 11
src/main/java/com/izouma/nineth/service/MetaAccessoriesService.java

@@ -12,6 +12,7 @@ import com.izouma.nineth.repo.AssetRepo;
 import com.izouma.nineth.repo.MetaAccessoriesPurchaseRecordRepo;
 import com.izouma.nineth.repo.MetaAccessoriesRepo;
 import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.web.MetaUserGoldController;
 import lombok.AllArgsConstructor;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.data.domain.Page;
@@ -31,6 +32,8 @@ public class MetaAccessoriesService {
 
     private MetaUserGoldService metaUserGoldService;
 
+    private MetaUserGoldController metaUserGoldController;
+
     private AssetRepo assetRepo;
 
     public Page<MetaAccessories> all(PageQuery pageQuery) {
@@ -38,23 +41,36 @@ public class MetaAccessoriesService {
     }
 
     @Transactional
-    public MetaRestResult<Integer> purchase(Long userId, Long metaAccessoriesId) {
-        MetaAccessoriesPurchaseRecord exist = metaAccessoriesPurchaseRecordRepo.findByUserIdAndMetaAccessoriesId(userId, metaAccessoriesId);
-        if (Objects.nonNull(exist)) {
-            return MetaRestResult.returnError("当前配饰已经购买过!");
+    public MetaRestResult<Integer> purchase(Long userId, List<Long> metaAccessoriesIds) {
+        List<MetaAccessoriesPurchaseRecord> exist = metaAccessoriesPurchaseRecordRepo.findByUserIdAndMetaAccessoriesIdIn(userId, metaAccessoriesIds);
+        if (CollectionUtils.isNotEmpty(exist)) {
+            return MetaRestResult.returnError("部分配饰已经购买过,请重新选择配饰!");
         }
-        MetaAccessories metaAccessories = metaAccessoriesRepo.findByIdAndDel(metaAccessoriesId, false);
-        if (Objects.isNull(metaAccessories)) {
-            return MetaRestResult.returnError("当前配饰信息不存在!");
+        int total = 0;
+        for (Long id : metaAccessoriesIds) {
+            MetaAccessories metaAccessories = metaAccessoriesRepo.findByIdAndDel(id, false);
+            if (Objects.isNull(metaAccessories)) {
+                return MetaRestResult.returnError(String.format("id:[%S]的配饰信息不存在!", id));
+            }
+            if (!EntryModeType.GOLD.equals(metaAccessories.getPurchaseMethod())) {
+                return MetaRestResult.returnError(String.format("当前配饰[%S]不允许金币购买!", id));
+            }
+            total = total + metaAccessories.getPrice();
         }
-        if (!EntryModeType.GOLD.equals(metaAccessories.getPurchaseMethod())) {
-            return MetaRestResult.returnError("当前配置不允许金币购买!");
+        MetaRestResult<Integer> restResultForNum = metaUserGoldController.queryGoldNum(userId);
+        if (Constants.MetaRestCode.success != restResultForNum.getCode()) {
+            return MetaRestResult.returnError(restResultForNum.getMessage());
         }
-        MetaRestResult<MetaUserGold> restResult = metaUserGoldService.changeNum(userId, -metaAccessories.getPrice());
+        if (total > restResultForNum.getData()) {
+            return MetaRestResult.returnError(String.format("金币不足:当前配饰总共需要金币[%S]个,当前用户剩余金币[%S]个", total, restResultForNum.getData()));
+        }
+        MetaRestResult<MetaUserGold> restResult = metaUserGoldService.changeNum(userId, -total);
         if (Constants.MetaRestCode.success != restResult.getCode()) {
             return MetaRestResult.returnError(restResult.getMessage());
         }
-        metaAccessoriesPurchaseRecordRepo.save(new MetaAccessoriesPurchaseRecord(userId, metaAccessoriesId));
+        metaAccessoriesIds.forEach(id -> {
+            metaAccessoriesPurchaseRecordRepo.save(new MetaAccessoriesPurchaseRecord(userId, id));
+        });
         return MetaRestResult.returnSuccess("购买成功", restResult.getData().getNum());
     }
 

+ 74 - 0
src/main/java/com/izouma/nineth/service/MetaBoatPositionService.java

@@ -0,0 +1,74 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.domain.MetaBoatPosition;
+import com.izouma.nineth.domain.MetaSpatialInfo;
+import com.izouma.nineth.domain.MetaSpatialWharf;
+import com.izouma.nineth.dto.MetaRestResult;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.MetaIsLandTypeEnum;
+import com.izouma.nineth.repo.MetaBoatPositionRepo;
+import com.izouma.nineth.repo.MetaSpatialInfoRepo;
+import com.izouma.nineth.repo.MetaSpatialWharfRepo;
+import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.utils.SecurityUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+
+@Service
+@AllArgsConstructor
+public class MetaBoatPositionService {
+
+    private MetaBoatPositionRepo metaBoatPositionRepo;
+
+    private MetaSpatialInfoRepo metaSpatialInfoRepo;
+
+    private MetaSpatialWharfRepo metaSpatialWharfRepo;
+
+    public Page<MetaBoatPosition> all(PageQuery pageQuery) {
+        return metaBoatPositionRepo.findAll(JpaUtils.toSpecification(pageQuery, MetaBoatPosition.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    public MetaRestResult<List<MetaBoatPosition>> queryBoatPosition(Long spaceInfoId) {
+        Long userId = SecurityUtils.getAuthenticatedUser().getId();
+        MetaSpatialInfo metaSpatialInfo = metaSpatialInfoRepo.findByIdAndDel(spaceInfoId, false);
+        if (Objects.isNull(metaSpatialInfo)) {
+            return MetaRestResult.returnError("查询不到空间信息");
+        }
+        if (!metaSpatialInfo.getUserId().equals(userId)) {
+            return MetaRestResult.returnError("该空间不属于你");
+        }
+        if (metaSpatialInfo.getType() != 2) {
+            return MetaRestResult.returnError("该空间不属于万岛空间");
+        }
+        MetaIsLandTypeEnum metaIsLandTypeEnum = queryIsLandType(metaSpatialInfo.getSize());
+        if (Objects.isNull(metaIsLandTypeEnum)) {
+            return MetaRestResult.returnError("该空间大小不合法");
+        }
+        List<MetaBoatPosition> metaBoatPositions = metaBoatPositionRepo.findAllByTypeAndDel(metaIsLandTypeEnum, false);
+        metaBoatPositions.forEach(metaBoatPosition -> {
+            MetaSpatialWharf metaSpatialWharf = metaSpatialWharfRepo.findAllByIsLandIdAndMetaBoatPositionIdAndDel(spaceInfoId, metaBoatPosition.getId(), false);
+            if (Objects.nonNull(metaSpatialWharf)) {
+                metaSpatialWharf.setMeUse(metaSpatialWharf.getUserId().equals(userId));
+                metaBoatPosition.setBoatInfo(metaSpatialWharf);
+            }
+        });
+        return MetaRestResult.returnSuccess(metaBoatPositions);
+    }
+
+    private MetaIsLandTypeEnum queryIsLandType(int size) {
+        switch (size) {
+            case 10000:
+                return MetaIsLandTypeEnum.TEN_THOUSAND;
+            case 60000:
+                return MetaIsLandTypeEnum.SIX_THOUSAND;
+            case 90000:
+                return MetaIsLandTypeEnum.NINE_THOUSAND;
+            default:
+                return null;
+        }
+    }
+}

+ 2 - 0
src/main/java/com/izouma/nineth/service/MetaGameBoxPointsService.java

@@ -13,6 +13,7 @@ import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 
+import javax.transaction.Transactional;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -50,6 +51,7 @@ public class MetaGameBoxPointsService {
         return MetaRestResult.returnSuccess(metaGameBoxPointsDTO);
     }
 
+    @Transactional
     public MetaRestResult<MetaGameBoxPoints> update(MetaGameBoxPoints record) {
         if (Objects.isNull(record)) {
             return MetaRestResult.returnError("Illegal parameter : parameter can not be null");

+ 112 - 0
src/main/java/com/izouma/nineth/service/MetaSpatialWharfService.java

@@ -0,0 +1,112 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.config.Constants;
+import com.izouma.nineth.domain.Asset;
+import com.izouma.nineth.domain.MetaSpatialWharf;
+import com.izouma.nineth.dto.MetaBoatDTO;
+import com.izouma.nineth.dto.MetaRestResult;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.AssetRepo;
+import com.izouma.nineth.repo.MetaSpatialWharfRepo;
+import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.utils.SecurityUtils;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Service
+@AllArgsConstructor
+public class MetaSpatialWharfService {
+
+    private MetaSpatialWharfRepo metaSpatialWharfRepo;
+
+    private AssetRepo assetRepo;
+
+    public Page<MetaSpatialWharf> all(PageQuery pageQuery) {
+        return metaSpatialWharfRepo.findAll(JpaUtils.toSpecification(pageQuery, MetaSpatialWharf.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    public MetaRestResult<MetaSpatialWharf> park(MetaSpatialWharf metaSpatialWharf) {
+        if (Objects.isNull(metaSpatialWharf)) {
+            return MetaRestResult.returnError("Illegal parameter : parameter can not be null");
+        }
+        if (Objects.isNull(metaSpatialWharf.getUserId())) {
+            return MetaRestResult.returnError("Illegal parameter : userId can not be null");
+        }
+        if (!metaSpatialWharf.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) {
+            return MetaRestResult.returnError("当前船只不属于你!");
+        }
+        if (Objects.isNull(metaSpatialWharf.getBoatId())) {
+            return MetaRestResult.returnError("Illegal parameter : boatId can not be null");
+        }
+        if (Objects.isNull(metaSpatialWharf.getIsLandId())) {
+            return MetaRestResult.returnError("Illegal parameter : isLandId can not be null");
+        }
+        if (StringUtils.isBlank(metaSpatialWharf.getBoatType())) {
+            return MetaRestResult.returnError("Illegal parameter : boatType can not be null");
+        }
+        if (Objects.isNull(metaSpatialWharf.getMetaBoatPositionId())) {
+            return MetaRestResult.returnError("Illegal parameter : metaBoatPositionId can not be null");
+        }
+        MetaSpatialWharf position = metaSpatialWharfRepo.findByMetaBoatPositionIdAndDel(metaSpatialWharf.getMetaBoatPositionId(), false);
+        if (Objects.nonNull(position)) {
+            return MetaRestResult.returnError(String.format("该位置已被船[%S]停靠", position.getBoatId()));
+        }
+        MetaSpatialWharf dbMetaSpatialWharf = metaSpatialWharfRepo.findByBoatIdAndUserIdAndDel(metaSpatialWharf.getBoatId(), metaSpatialWharf.getUserId(), false);
+        if (Objects.nonNull(dbMetaSpatialWharf)) {
+            return MetaRestResult.returnError(String.format("该船只已经停靠在岛屿[%S]", dbMetaSpatialWharf.getIsLandId()));
+        }
+        Asset asset = assetRepo.findByIdAndUserIdAndDel(metaSpatialWharf.getBoatId(), metaSpatialWharf.getUserId(), false);
+        if (Objects.isNull(asset)) {
+            return MetaRestResult.returnError(String.format("藏品[%S]不存在", metaSpatialWharf.getBoatId()));
+        }
+        metaSpatialWharf.setBoatImg(asset.getPic().get(0).getUrl());
+        return MetaRestResult.returnSuccess("停靠成功", metaSpatialWharfRepo.save(metaSpatialWharf));
+    }
+
+    private String getRarityType(String name) {
+        if (StringUtils.isBlank(name)) {
+            return null;
+        }
+        if (name.contains(Constants.Rarity.U) && !name.contains(Constants.Rarity.UR)) {
+            return Constants.Rarity.U;
+        }
+        if (name.contains(Constants.Rarity.R) && !name.contains(Constants.Rarity.SR)) {
+            return Constants.Rarity.R;
+        }
+        if (name.contains(Constants.Rarity.SR) && !name.contains(Constants.Rarity.SSR)) {
+            return Constants.Rarity.SR;
+        }
+        if (name.contains(Constants.Rarity.SSR)) {
+            return Constants.Rarity.SSR;
+        }
+        if (name.contains(Constants.Rarity.UR)) {
+            return Constants.Rarity.UR;
+        }
+        return null;
+    }
+
+    public MetaRestResult<List<MetaBoatDTO>> queryBoats() {
+        List<Long> parkingBoatIds = metaSpatialWharfRepo.findParkingBoatIds(SecurityUtils.getAuthenticatedUser().getId());
+        List<Asset> assets = assetRepo.findAllBoats("僵尸动物园", Constants.META_NORMAL_STATUS, parkingBoatIds);
+        List<MetaBoatDTO> metaBoatDTOS = new ArrayList<>();
+        try {
+            assets.forEach(asset -> {
+                String rarityType = getRarityType(asset.getName());
+                if (StringUtils.isBlank(rarityType)) {
+                    throw new BusinessException("船只类型查询失败!");
+                }
+                metaBoatDTOS.add(new MetaBoatDTO(asset.getId(), asset.getPic().get(0).getUrl(), rarityType));
+            });
+        } catch (Exception e) {
+            return MetaRestResult.returnError(e.getMessage());
+        }
+        return MetaRestResult.returnSuccess(metaBoatDTOS);
+    }
+}

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

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

+ 16 - 0
src/main/java/com/izouma/nineth/utils/MathUtils.java

@@ -0,0 +1,16 @@
+package com.izouma.nineth.utils;
+
+
+public class MathUtils {
+
+    /**
+     * 返回范围内内随机数
+     *
+     * @param min 最小值
+     * @param max 最大值
+     * @return 随机数
+     */
+    public static int random(int min, int max) {
+        return (int) (min + Math.random() * (max - min + 1));
+    }
+}

+ 1 - 0
src/main/java/com/izouma/nineth/utils/excel/ExcelUtils.java

@@ -38,6 +38,7 @@ public class ExcelUtils<T> {
                 .registerConverter(new OperationSourceConverter())
                 .registerConverter(new RecordTypeConverter())
                 .registerConverter(new MetaPointTypeEnumConverter())
+                .registerConverter(new MetaIsLandTypeEnumConverter())
                 .doWrite(data);
     }
 }

+ 42 - 0
src/main/java/com/izouma/nineth/utils/excel/MetaIsLandTypeEnumConverter.java

@@ -0,0 +1,42 @@
+package com.izouma.nineth.utils.excel;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.izouma.nineth.enums.MetaIsLandTypeEnum;
+
+public class MetaIsLandTypeEnumConverter implements Converter<MetaIsLandTypeEnum> {
+
+    @Override
+    public Class supportJavaTypeKey() {
+        return MetaIsLandTypeEnum.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return null;
+    }
+
+    @Override
+    public MetaIsLandTypeEnum convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        try {
+            for (MetaIsLandTypeEnum value : MetaIsLandTypeEnum.values()) {
+                if (value.getDescription().equals(cellData.getStringValue())) {
+                    return value;
+                }
+            }
+        } catch (Exception ignored) {
+        }
+        return null;
+    }
+
+    @Override
+    public CellData convertToExcelData(MetaIsLandTypeEnum value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        if (value != null) {
+            return new CellData(value.getDescription());
+        }
+        return null;
+    }
+}

+ 2 - 5
src/main/java/com/izouma/nineth/web/MetaAccessoriesController.java

@@ -5,7 +5,6 @@ import com.izouma.nineth.dto.MetaRestResult;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.enums.EntryModeType;
 import com.izouma.nineth.exception.BusinessException;
-import com.izouma.nineth.repo.MetaAccessoriesPurchaseRecordRepo;
 import com.izouma.nineth.repo.MetaAccessoriesRepo;
 import com.izouma.nineth.service.MetaAccessoriesService;
 import com.izouma.nineth.utils.ObjUtils;
@@ -26,8 +25,6 @@ public class MetaAccessoriesController extends BaseController {
     private MetaAccessoriesService metaAccessoriesService;
     private MetaAccessoriesRepo metaAccessoriesRepo;
 
-    private MetaAccessoriesPurchaseRecordRepo metaAccessoriesPurchaseRecordRepo;
-
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
     public MetaAccessories save(@RequestBody MetaAccessories record) {
@@ -74,8 +71,8 @@ public class MetaAccessoriesController extends BaseController {
     }
 
     @PostMapping("/purchase")
-    public MetaRestResult<Integer> purchase(Long userId, Long metaAccessoriesId) {
-        return metaAccessoriesService.purchase(userId, metaAccessoriesId);
+    public MetaRestResult<Integer> purchase(@RequestParam Long userId, @RequestParam List<Long> metaAccessoriesIds) {
+        return metaAccessoriesService.purchase(userId, metaAccessoriesIds);
     }
 
     @GetMapping("/{userId}/hold")

+ 72 - 0
src/main/java/com/izouma/nineth/web/MetaBoatPositionController.java

@@ -0,0 +1,72 @@
+package com.izouma.nineth.web;
+
+import com.izouma.nineth.domain.MetaBoatPosition;
+import com.izouma.nineth.dto.MetaRestResult;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.MetaBoatPositionRepo;
+import com.izouma.nineth.repo.MetaSpatialInfoRepo;
+import com.izouma.nineth.repo.MetaSpatialWharfRepo;
+import com.izouma.nineth.service.MetaBoatPositionService;
+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;
+
+@RestController
+@RequestMapping("/metaBoatPosition")
+@AllArgsConstructor
+public class MetaBoatPositionController extends BaseController {
+    private MetaBoatPositionService metaBoatPositionService;
+    private MetaBoatPositionRepo metaBoatPositionRepo;
+
+    private MetaSpatialInfoRepo metaSpatialInfoRepo;
+
+    private MetaSpatialWharfRepo metaSpatialWharfRepo;
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public MetaBoatPosition save(@RequestBody MetaBoatPosition record) {
+        if (record.getId() != null) {
+            MetaBoatPosition orig = metaBoatPositionRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return metaBoatPositionRepo.save(orig);
+        }
+        return metaBoatPositionRepo.save(record);
+    }
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<MetaBoatPosition> all(@RequestBody PageQuery pageQuery) {
+        return metaBoatPositionService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public MetaBoatPosition get(@PathVariable Long id) {
+        return metaBoatPositionRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        metaBoatPositionRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<MetaBoatPosition> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+
+    @GetMapping("/{spaceInfoId}/queryBoatPosition")
+    public MetaRestResult<List<MetaBoatPosition>> queryBoatPosition(@PathVariable Long spaceInfoId) {
+        return metaBoatPositionService.queryBoatPosition(spaceInfoId);
+    }
+}
+

+ 11 - 0
src/main/java/com/izouma/nineth/web/MetaSpatialInfoController.java

@@ -6,8 +6,10 @@ import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.MetaSpatialInfoRepo;
 import com.izouma.nineth.service.MetaSpatialInfoService;
+import com.izouma.nineth.utils.MathUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
+import org.apache.commons.collections.CollectionUtils;
 import org.springframework.data.domain.Page;
 import org.springframework.web.bind.annotation.*;
 
@@ -72,5 +74,14 @@ public class MetaSpatialInfoController extends BaseController {
         }
         return MetaRestResult.returnSuccess(metaSpatialInfo);
     }
+
+    @GetMapping("/{userId}/{type}/random")
+    public MetaRestResult<MetaSpatialInfo> random(@PathVariable Long userId, @PathVariable int type) {
+        List<MetaSpatialInfo> metaSpatialInfos = metaSpatialInfoRepo.findByTypeAndUserIdNot(type, userId);
+        if (CollectionUtils.isEmpty(metaSpatialInfos)) {
+            return MetaRestResult.returnError("当前没有符合的空间");
+        }
+        return MetaRestResult.returnSuccess(metaSpatialInfos.get(MathUtils.random(0, metaSpatialInfos.size()-1)));
+    }
 }
 

+ 82 - 0
src/main/java/com/izouma/nineth/web/MetaSpatialWharfController.java

@@ -0,0 +1,82 @@
+package com.izouma.nineth.web;
+
+import com.izouma.nineth.domain.MetaSpatialWharf;
+import com.izouma.nineth.dto.MetaBoatDTO;
+import com.izouma.nineth.dto.MetaRestResult;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.repo.MetaSpatialWharfRepo;
+import com.izouma.nineth.service.MetaSpatialWharfService;
+import com.izouma.nineth.utils.SecurityUtils;
+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("/metaSpatialWharf")
+@AllArgsConstructor
+public class MetaSpatialWharfController extends BaseController {
+    private MetaSpatialWharfService metaSpatialWharfService;
+
+    private MetaSpatialWharfRepo metaSpatialWharfRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<MetaSpatialWharf> all(@RequestBody PageQuery pageQuery) {
+        return metaSpatialWharfService.all(pageQuery);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<MetaSpatialWharf> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+
+    @PostMapping("/park")
+    public MetaRestResult<MetaSpatialWharf> park(@RequestBody MetaSpatialWharf metaSpatialWharf) {
+        return metaSpatialWharfService.park(metaSpatialWharf);
+    }
+
+    @PostMapping("/back")
+    public MetaRestResult<Void> back(Long boatId) {
+        MetaSpatialWharf metaSpatialWharf = metaSpatialWharfRepo.findByBoatIdAndDel(boatId, false);
+        if (Objects.isNull(metaSpatialWharf)) {
+            return MetaRestResult.returnError("当前船只停靠信息为空!");
+        }
+        if (!metaSpatialWharf.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) {
+            return MetaRestResult.returnError("当前船只不属于你!");
+        }
+        metaSpatialWharfRepo.back(boatId);
+        return MetaRestResult.returnSuccess("收回船只成功!");
+    }
+
+    @PostMapping("/backAll")
+    public MetaRestResult<Void> backAll() {
+        metaSpatialWharfRepo.backAll(SecurityUtils.getAuthenticatedUser().getId());
+        return MetaRestResult.returnSuccess("收回船只成功!");
+    }
+
+    @GetMapping("/{boatId}/myself")
+    public MetaRestResult<Boolean> myself(@PathVariable Long boatId) {
+        MetaSpatialWharf metaSpatialWharf = metaSpatialWharfRepo.findByBoatIdAndDel(boatId, false);
+        if (Objects.isNull(metaSpatialWharf)) {
+            return MetaRestResult.returnError("当前船只停靠信息为空!");
+        }
+        if (metaSpatialWharf.getUserId().equals(SecurityUtils.getAuthenticatedUser().getId())) {
+            return MetaRestResult.returnSuccess(Boolean.TRUE);
+        }
+        return MetaRestResult.returnSuccess(Boolean.FALSE);
+    }
+
+    @GetMapping("/queryBoats")
+    public MetaRestResult<List<MetaBoatDTO>> queryBoatsNotParking() {
+        return metaSpatialWharfService.queryBoats();
+    }
+}
+

+ 46 - 0
src/main/java/com/izouma/nineth/web/MetaVisitorController.java

@@ -0,0 +1,46 @@
+package com.izouma.nineth.web;
+
+import com.izouma.nineth.domain.MetaVisitor;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.repo.MetaVisitorRepo;
+import com.izouma.nineth.service.MetaVisitorService;
+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;
+
+@RestController
+@RequestMapping("/metaVisitor")
+@AllArgsConstructor
+public class MetaVisitorController extends BaseController {
+    private MetaVisitorService metaVisitorService;
+    private MetaVisitorRepo metaVisitorRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<MetaVisitor> all(@RequestBody PageQuery pageQuery) {
+        return metaVisitorService.all(pageQuery);
+    }
+
+    @PostMapping("/taboo/{id}")
+    public void taboo(@PathVariable Long id) {
+        metaVisitorRepo.taboo(id);
+    }
+
+    @PostMapping("/cancelTaboo/{id}")
+    public void cancelTaboo(@PathVariable Long id) {
+        metaVisitorRepo.cancelTaboo(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<MetaVisitor> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 8 - 0
src/main/java/com/izouma/nineth/web/PublicScreenChatController.java

@@ -2,6 +2,7 @@ package com.izouma.nineth.web;
 
 import com.izouma.nineth.domain.PublicScreenChat;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.repo.PublicScreenChatRepo;
 import com.izouma.nineth.service.PublicScreenChatService;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
@@ -18,6 +19,8 @@ import java.util.List;
 public class PublicScreenChatController extends BaseController {
     private PublicScreenChatService publicScreenChatService;
 
+    private PublicScreenChatRepo publicScreenChatRepo;
+
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/all")
     public Page<PublicScreenChat> all(@RequestBody PageQuery pageQuery) {
@@ -31,5 +34,10 @@ public class PublicScreenChatController extends BaseController {
         List<PublicScreenChat> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data);
     }
+
+    @PostMapping("/recall/{id}")
+    public void recall(@PathVariable Long id) {
+        publicScreenChatRepo.recall(id);
+    }
 }
 

+ 20 - 0
src/main/java/com/izouma/nineth/web/UserDetailController.java

@@ -40,6 +40,26 @@ public class UserDetailController extends BaseController {
             if (!contentAuditService.auditText(record.getAutograph())) {
                 throw new BusinessException("简介包含非法内容");
             }
+        }if (StringUtils.isNotBlank(record.getNickname())) {
+            if (!contentAuditService.auditText(record.getNickname())) {
+                throw new BusinessException("昵称包含非法内容");
+            }
+        }if (StringUtils.isNotBlank(record.getMail())) {
+            if (!contentAuditService.auditText(record.getMail())) {
+                throw new BusinessException("邮箱包含非法内容");
+            }
+        }if (StringUtils.isNotBlank(record.getSchool())) {
+            if (!contentAuditService.auditText(record.getSchool())) {
+                throw new BusinessException("学校包含非法内容");
+            }
+        }if (StringUtils.isNotBlank(record.getCompany())) {
+            if (!contentAuditService.auditText(record.getCompany())) {
+                throw new BusinessException("公司包含非法内容");
+            }
+        }if (StringUtils.isNotBlank(record.getOccupation())) {
+            if (!contentAuditService.auditText(record.getOccupation())) {
+                throw new BusinessException("职业包含非法内容");
+            }
         }
         return userDetailRepo.save(record);
     }

+ 1 - 0
src/main/resources/genjson/MetaBoatPosition.json

@@ -0,0 +1 @@
+{"tableName":"MetaBoatPosition","className":"MetaBoatPosition","remark":"空间船位管理","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/java/com/izouma/nineth","viewPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/vue/src/views","routerPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/vue/src","resourcesPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"isLandId","modelName":"isLandId","remark":"岛屿ID","showInList":true,"showInForm":true,"formType":"number","required":true,"validate":false},{"name":"type","modelName":"type","remark":"岛屿类型","showInList":false,"showInForm":false,"formType":"singleLineText"},{"name":"boatPos","modelName":"boatPos","remark":"位置信息","showInList":true,"showInForm":true,"formType":"singleLineText","required":true},{"name":"boatRot","modelName":"boatRot","remark":"旋转值","showInList":true,"showInForm":true,"formType":"singleLineText","required":true}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.nineth","tablePackage":"com.izouma.nineth.domain.MetaBoatPosition"}

+ 1 - 0
src/main/resources/genjson/MetaSpatialWharf.json

@@ -0,0 +1 @@
+{"tableName":"MetaSpatialWharf","className":"MetaSpatialWharf","remark":"码头船只列表","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/java/com/izouma/nineth","viewPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/vue/src/views","routerPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/vue/src","resourcesPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"isLandId","modelName":"isLandId","remark":"岛屿ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"boatId","modelName":"boatId","remark":"船只ID","showInList":true,"showInForm":true,"formType":"number"},{"name":"boatImg","modelName":"boatImg","remark":"船只图片","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"boatType","modelName":"boatType","remark":"船只类型","showInList":true,"showInForm":true,"formType":"select","apiFlag":"1","optionsValue":"[{\"label\":\"U\",\"value\":\"U\"},{\"label\":\"R\",\"value\":\"R\"},{\"label\":\"SR\",\"value\":\"SR\"},{\"label\":\"SSR\",\"value\":\"SSR\"},{\"label\":\"UR\",\"value\":\"UR\"}]"},{"name":"boatPos","modelName":"boatPos","remark":"位置信息","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"boatRot","modelName":"boatRot","remark":"旋转值","showInList":true,"showInForm":true,"formType":"singleLineText"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.nineth","tablePackage":"com.izouma.nineth.domain.MetaSpatialWharf"}

+ 1 - 0
src/main/resources/genjson/MetaVisitor.json

@@ -0,0 +1 @@
+{"tableName":"MetaVisitor","className":"MetaVisitor","remark":"游客管理","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/java/com/izouma/nineth","viewPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/vue/src/views","routerPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/vue/src","resourcesPath":"/Users/xiaohuoban/IdeaProjects/raex_back/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"avatar","modelName":"avatar","remark":"头像","showInList":true,"showInForm":true,"formType":"singleLineText"},{"name":"nickname","modelName":"nickname","remark":"昵称","showInList":true,"showInForm":true,"formType":"singleLineText"}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.nineth","tablePackage":"com.izouma.nineth.domain.MetaVisitor"}

+ 265 - 109
src/main/resources/static/Agreement.html

@@ -1,47 +1,55 @@
 <!DOCTYPE html>
 <!-- saved from url=(0039)https://crypts.cn/protocol/privacy.html -->
-<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-  
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
+<html lang="en">
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+
+  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
   <title>OASISMETA绿洲平台隐私政策</title>
   <style>
-    html,body{
+    html,
+    body {
       background: #181818;
       color: white;
     }
   </style>
-<style>hcfy-result.__hcfy__result__loaded__.__hcfy__result__both__{border: 1px dotted}</style></head>
+  <style>
+    hcfy-result.__hcfy__result__loaded__.__hcfy__result__both__ {
+      border: 1px dotted;
+    }
+  </style>
+</head>
+
 <body>
   <div class="page-container">
     <h1 class="align-center">OASISMETA绿洲平台隐私政策</h1>
-    <h4>生效时间【2022-04-11】</h4>
-    <h4>更新时间【2022-04-11】</h4>
+    <h4>生效时间【2022-12.19】</h4>
+    <h4>更新时间【2022-12.19】</h4>
     <p class="text-content">
       华储艺术品中心(以下称“我们”或“公司”)深知个人信息安全的重要性,我们将按照法律法规要求,采用安全保护措施,保护您的个人信息及隐私安全。因此,我们制定《OASISMETA绿洲平台隐私政策》(以下简称“《隐私政策》”)并提醒您:在使用“OASISMETA绿洲平台”及相关服务(定义同《OASISMETA绿洲平台用户协议》)前,请务必仔细阅读并透彻理解本《隐私政策》,在确认充分理解并同意后,按照指引作出您的适当选择。
     </p>
     <p class="strong-text">本隐私政策将帮助您了解:</p>
     <p class="text-content">
-      我们会遵循隐私政策收集、使用您的信息,但不会仅因您同意本隐私政策而采用强制捆绑的方式一揽子收集个人信息。
-    </p>
+      我们会遵循隐私政策收集、使用您的信息,但不会仅因您同意本隐私政策而采用强制捆绑的方式一揽子收集个人信息。 </p>
     <p class="text-content">
       当您使用或开启相关功能或使用服务时,为实现功能、服务所必需,我们会收集、使用相关信息。除非是为实现基本业务功能或根据法律法规要求所必需的必要信息,您均可以拒绝提供且不影响其他功能或服务。我们将在隐私政策中逐项说明哪些是必要信息。
     </p>
     <p class="text-content">
-      如果您未登录帐号,我们会通过设备对应的标识符信息来保障信息推送的基本功能。如果您登录了帐号,我们会根据帐号信息实现信息推送。
-    </p>
+      如果您未登录帐号,我们会通过设备对应的标识符信息来保障信息推送的基本功能。如果您登录了帐号,我们会根据帐号信息实现信息推送。 </p>
     <p class="text-content">
-      <span class="strong-text">APP端 相机、相册(存储)、电话、日历权限,</span>
+      <span class="strong-text">APP端 相机、相册(存储)、电话、日历权限, </span>
       <span>均不会默认开启,只有经过您的明示授权才会在为实现特定功能或服务时使用,您也可以撤回授权。</span>
-      <span class="strong-text">特别需要指出的是,即使经过您的授权,我们获得了这些敏感权限,也不会在相关功能或服务不需要时而收集您的信息。具体权限申请及权限使用情况请见:</span>
-      <span>OASISMETA绿洲平台应用权限申请与使用情况说明</span>
+      <span class="strong-text">特别需要指出的是,即使经过您的授权,我们获得了这些敏感权限,也不会在相关功能或服务不需要时而收集您的信息。具体权限申请及权限使用情况请见: >
+        <span>OASISMETA绿洲平台应用权限申请与使用情况说明</span>
     </p>
     <p class="text-content">
       本隐私政策适用于您通过OASISMETA绿洲平台应用程序、OASISMETA绿洲平台官方网站、供第三方网站和应用程序使用的OASISMETA绿洲平台软件开发工具包(SDK)和应用程序编程接口(API)方式来访问和使用我们的产品和服务。
     </p>
     <p class="text-content">
-      下文将帮您详细了解我们如何收集、使用、存储、传输、共享、转让(如适用)与保护个人信息;帮您了解查询、访问、删除、更正、撤回授权个人信息的方式。其中,
-      <span class="strong-text">有关您个人信息权益的条款等重要内容我们已用加粗形式提示,请特别关注。</span>
+      下文将帮您详细了解我们如何收集、使用、存储、传输、共享、转让(如适用)与保护个人信息;帮您了解查询、访问、删除、更正、撤回授权个人信息的方式。其中, <span
+        class="strong-text"> 有关您个人信息权益的条款等重要内容我们已用加粗形式提示,请特别关注。</span>
     </p>
     <p class="text-content">一、我们如何收集和使用个人信息</p>
     <p class="text-content">二、我们对Cookie 和同类技术的使用</p>
@@ -55,77 +63,128 @@
     <p class="text-content">十、其他</p>
     <h4>一、我们如何收集和使用个人信息</h4>
     <h5>(一)我们主动收集与使用的个人信息</h5>
-    <p class="text-content">我们会按照如下方式收集你在使用服务时主动提供的,以及通过自动化手段收集您在使用功能或接受服务过程中产生的信息:</p>
+    <p class="text-content">
+      我们会按照如下方式收集你在使用服务时主动提供的,以及通过自动化手段收集您在使用功能或接受服务过程中产生的信息:
+    </p>
     <h6>1、注册、认证、登录“OASISMETA绿洲平台”和相关服务</h6>
-    <p class="text-content">(1)当您注册、登录“OASISMETA绿洲平台”及相关服务时,你可以通过手机号创建账号,我们将通过发送短信验证码来验证您的身份是否有效,并且您可完善相关的网络身份识别信息(头像、用户名),收集这些信息是为了帮助你完成注册。您还可根据自身需求选择填写个人介绍等信息完善你的个人信息。</p>
-    <p class="text-content">(2)在您使用身份认证的功能或相关服务所需时,根据相关法律法规,
+    <p class="text-content">
+      (1)当您注册、登录“OASISMETA绿洲平台”及相关服务时,你可以通过手机号创建账号,我们将通过发送短信验证码来验证您的身份是否有效,并且您可完善相关的网络身份识别信息(用户名),收集这些信息是为了帮助你完成注册。您还可根据自身需求选择填写用户名、邮箱、简介、公司、学校、职业,完善你的个人信息。
+    </p>
+    <p class="text-content">
+      (2)在您使用身份认证的功能或相关服务所需时,根据相关法律法规, 
       <span class="strong-text">您可能需要提供您的真实身份信息(真实姓名、身份证号码以及进行实名认证所需要的其他信息)以完成实名验证。 这些信息属于个人敏感信息,</span>
-      您可以拒绝提供,如果拒绝提供您将可能无法获得相关服务,但不影响其他功能与服务的正常使用。
+       您可以拒绝提供,如果拒绝提供您将可能无法获得相关服务,但不影响其他功能与服务的正常使用。
     </p>
     <h6>2、资讯浏览和咨询服务</h6>
-    <p class="text-content">(1)为保障内容的质量并向您提供更好的服务,我们可能会收集必要的日志信息。</p>
-    <p class="text-content">(2)用于信息展示和咨询服务的日志信息包括:
-      您操作、使用的行为信息:点击、关注、收藏、搜索、浏览、分享
-      ,您主动提供的信息:反馈<span class="strong-text">GPS信息、WLAN接入点</span> 、蓝牙和基站等传感器信息</p>
+    <p class="text-content">
+      (1)为保障内容的质量并向您提供更好的服务,我们可能会收集必要的日志信息。
+    </p>
+    <p class="text-content">
+      (2)用于信息展示和咨询服务的日志信息包括: 您操作、使用的行为信息:点击、关注、收藏、搜索、浏览、分享 ,您主动提供的信息:反馈<span class="strong-text">GPS信息、WLAN接入点 </span>
+      、蓝牙和基站传感器信息
+    </p>
     <!-- <p class="text-content">
       (3)<span class="strong-text">地理位置是敏感个人信息</span> ,若你拒绝提供,我们将不会根据GPS信息向你推荐信息,且不会影响OASISMETA绿洲平台其他功能的正常使用。
     </p> -->
     <!-- <p class="text-content">(4)我们会基于IP地址对应的城市向您展示、推荐您所在地区的本地相关信息或提供相应的咨询服务。</p> -->
-    <p class="text-content">(3)我们收集、使用的上述信息进行了去标识化处理,数据分析仅对应特定的、无法直接关联您身份的编码,不会与您的真实身份相关联。</p>
+    <p class="text-content">
+      (3)我们收集、使用的上述信息进行了去标识化处理,数据分析仅对应特定的、无法直接关联您身份的编码,不会与您的真实身份相关联。 </p>
     <h6>3、为你提供信息发布功能或服务</h6>
     <p class="text-content">
-      您发布内容、评论、评价、提问或回答时,我们将收集您发布的信息,并展示您的昵称、头像、发布内容等。
+      您发布内容或回答时,我们将收集您发布的信息,并展示您的昵称、头像、发布内容等。 </p>
+    <p class="text-content">
+      (1)您使用上传图片、发布音视频功能时,我们会请求您授权相机、<span
+        class="strong-text">相册(存储)、照片、麦克风权限。您如果拒绝授权提供,将无法使用此功能,但不影响您正常使用“OASISMETA绿洲平台”的其他功能。</span>
+    </p>
+    <p class="text-content">
+      (2)您发布信息并选择显示位置时,我们会请求您授权 
+      <span class="strong-text">地理位置权限,并收集与本服务相关的位置信息。您如果拒绝授权提供,将无法使用此功能,但不影响您正常使用“OASISMETA绿洲平台”的其他功能。</span>
     </p>
-    <p class="text-content">(1)您使用上传图片、发布音视频功能时,我们会请求您授权相机、<span class="strong-text">相册(存储)、照片、麦克风权限。您如果拒绝授权提供,将无法使用此功能,但不影响您正常使用“OASISMETA绿洲平台”的其他功能。</span> </p>
-    <p class="text-content">(2)您发布信息并选择显示位置时,我们会请求您授权 <span class="strong-text">地理位置权限,并收集与本服务相关的位置信息。您如果拒绝授权提供,将无法使用此功能,但不影响您正常使用“OASISMETA绿洲平台”的其他功能。</span></p>
     <h6>4、为您提供互动功能或服务</h6>
     <p class="text-content">
-      (1)您主动关注您感兴趣的账号、话题并与之进行互动,进行浏览、评论、收藏、点赞或分享内容时,我们会收集您关注的账号,并向您展示您关注账号发布内容。
+      (1)您主动关注您感兴趣的账号、话题并与之进行互动,进行浏览、收藏、点赞或分享内容时,我们会收集您关注的账号,并向您展示您关注账号发布内容。
     </p>
-    <p class="text-content">(2)为了实现口令分享功能,我们需要访问您的剪切板,读取其中包含的口令、分享码、链接,以实现跳转、分享、活动联动等功能或服务。</p>
+    <p class="text-content">
+      (2)为了实现口令分享功能,我们需要访问您的剪切板,读取其中包含的口令、分享码、链接,以实现跳转、分享、活动联动等功能或服务。 </p>
     <h6>5、开展营销活动</h6>
     <p class="text-content">
-      当您选择参加OASISMETA绿洲平台举办的有关营销活动时,根据活动可能需要您提供<span class="strong-text">姓名、通信地址、联系方式、身份证号、银行账号信息。这些信息可能包括个人敏感信息,如果您拒绝提供这些信息,</span>可能影响您参加相关活动或领取奖品,但不会影响其他功能。
+      当您选择参加OASISMETA绿洲平台举办的有关营销活动时,根据活动可能需要您提供<span
+        class="strong-text">姓名、通信地址、联系方式、身份证号、银行账号信息。这些信息可能包括个人敏感信息,如果您拒绝提供这些信息,</span>可能影响您参加相关活动或领取奖品,但不会影响其他功能。
     </p>
     <h6>6、支付功能</h6>
     <p class="text-content">
       在您下单后,您可以选择与OASISMETA绿洲平台合作的第三方支付机构所提供的支付服务。我们需要将您的订单金额信息和订单支付相关信息与这些支付机构共享以实现其确认您的支付指令并完成支付。为使我们及时获悉并确认您的支付进度及状态,为您提供售后与争议解决服务,您同意我们可自您所选择的流转对象或您选择的其他金融机构处收集与支付进度相关信息。
     </p>
     <h6>7、客服</h6>
-    <p class="text-content">(1)当您与我们联系或提出咨询、投诉、争议纠纷处理等申请时,为了保障您的账户及系统安全,<span class="strong-text">我们需要您提供必要的个人信息以核验您的身份、为您提供相关服务。</span></p>
+    <p class="text-content">
+      (1)当您与我们联系或提出咨询、投诉、争议纠纷处理等申请时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息以核验您的身份、为您提供相关服务。</p>
     <p class="text-content">
       <span class="strong-text">
-        (2)为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的通信/通话记录及相关内容(包括账号信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。
-      </span>
+        (2)为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的通信/通话记录及相关内容(包括账号信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。 </span>
     </p>
-    <p class="text-content">(3)为了提供服务及改进服务质量的合理需要,我们还可能使用您的其他信息,包括您与客服联系时您提供的相关信息。</p>
+    <p class="text-content">
+      (3)为了提供服务及改进服务质量的合理需要,我们还可能使用您的其他信息,包括您与客服联系时您提供的相关信息。</p>
     <h5>(二)收集、使用个人信息目的变更的处理</h5>
-    <p class="text-content">请您了解,随着我们业务的发展,可能会对“OASISMETA绿洲平台”的功能和提供的服务有所调整变化。原则上,当新功能或服务与我们当前提供的功能或服务相关时,收集与使用的个人信息将与原处理目的具有直接或合理关联。在与原处理目的无直接或合理关联的场景下,我们收集、使用您的个人信息,会再次进行告知,并征得您的同意。</p>
+    <p class="text-content">
+      请您了解,随着我们业务的发展,可能会对“OASISMETA绿洲平台”的功能和提供的服务有所调整变化。原则上,当新功能或服务与我们当前提供的功能或服务相关时,收集与使用的个人信息将与原处理目的具有直接或合理关联。在与原处理目的无直接或合理关联的场景下,我们收集、使用您的个人信息,会再次进行告知,并征得您的同意。
+    </p>
     <h5>(三)依法豁免征得同意收集和使用的个人信息</h5>
-    <p class="text-content">请您理解,在下列情形中,根据法律法规及相关国家标准,我们收集和使用您的个人信息无需征得您的授权同意:</p>
+    <p class="text-content">
+      请您理解,在下列情形中,根据法律法规及相关国家标准,我们收集和使用您的个人信息无需征得您的授权同意: </p>
     <p class="text-content">1、与国家安全、国防安全直接相关的</p>
-    <p class="text-content">2、与公共安全、公共卫生、重大公共利益直接相关的</p>
-    <p class="text-content">3、与犯罪侦查、起诉、审判和判决执行等直接相关的</p>
-    <p class="text-content">4、出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的</p>
-    <p class="text-content">5、所收集的您的个人信息是您自行向社会公众公开的;</p>
-    <p class="text-content">6、从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道</p>
+    <p class="text-content">
+      2、与公共安全、公共卫生、重大公共利益直接相关的
+    </p>
+    <p class="text-content">
+      3、与犯罪侦查、起诉、审判和判决执行等直接相关的
+    </p>
+    <p class="text-content">
+      4、出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的
+    </p>
+    <p class="text-content">
+      5、所收集的您的个人信息是您自行向社会公众公开的;
+    </p>
+    <p class="text-content">
+      6、从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道
+    </p>
     <p class="text-content">7、根据您的要求签订或履行合同所必需的</p>
-    <p class="text-content">8、用于维护“OASISMETA绿洲平台”及相关服务的安全稳定运行所必需的,例如发现、处置“OASISMETA绿洲平台”及相关服务的故障</p>
+    <p class="text-content">
+      8、用于维护“OASISMETA绿洲平台”及相关服务的安全稳定运行所必需的,例如发现、处置“OASISMETA绿洲平台”及相关服务的故障
+    </p>
     <p class="text-content">9、为合法的新闻报道所必需的</p>
-    <p class="text-content">10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的</p>
+    <p class="text-content">
+      10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的
+    </p>
     <p class="text-content">11、法律法规规定的其他情形</p>
-    <p class="text-content"><span class="strong-text">
-      特别提示您注意,如信息无法单独或结合其他信息识别到您的个人身份,其不属于法律意义上您的个人信息;当您的信息可以单独或结合其他信息识别到您的个人身份时或我们将无法与任何特定个人信息建立联系的数据与其他您的个人信息结合使用时,这些信息在结合使用期间,将作为您的个人信息按照本隐私政策处理与保护。
-    </span></p>
+    <p class="text-content">
+      <span class="strong-text">
+        特别提示您注意,如信息无法单独或结合其他信息识别到您的个人身份,其不属于法律意义上您的个人信息;当您的信息可以单独或结合其他信息识别到您的个人身份时或我们将无法与任何特定个人信息建立联系的数据与其他您的个人信息结合使用时,这些信息在结合使用期间,将作为您的个人信息按照本隐私政策处理与保护。
+      </span>
+    </p>
     <h4>二、对Cookie和同类技术的使用</h4>
-    <p class="text-content">Cookie和同类技术是互联网中的通用常用技术。当您使用“OASISMETA绿洲平台”及相关服务时,我们可能会使用相关技术向您的设备发送一个或多个Cookie或匿名标识符,以收集和存储您访问、使用本产品时的信息。我们使用 Cookie 和同类技术主要为了实现以下功能或服务:</p>
+    <p class="text-content">
+      Cookie和同类技术是互联网中的通用常用技术。当您使用“OASISMETA绿洲平台”及相关服务时,我们可能会使用相关技术向您的设备发送一个或多个Cookie或匿名标识符,以收集和存储您访问、使用本产品时的信息。我们使用
+      Cookie 和同类技术主要为了实现以下功能或服务:
+    </p>
     <h5>(一)保障产品与服务的安全、高效运转</h5>
-    <p class="text-content">我们可能会设置认证与保障安全性的cookie 或匿名标识符,使我们确认您是否安全登录服务,或者是否遇到盗用、欺诈等不法行为。这些技术还会帮助我们改进服务效率,提升登录和响应速度。</p>
+    <p class="text-content">
+      我们可能会设置认证与保障安全性的cookie
+      或匿名标识符,使我们确认您是否安全登录服务,或者是否遇到盗用、欺诈等不法行为。这些技术还会帮助我们改进服务效率,提升登录和响应速度。
+    </p>
     <h5>(二)帮助您获得更轻松的访问体验</h5>
-    <p class="text-content">我们可能会设置认证与保障安全性的cookie 或匿名标识符,使我们确认您是否安全登录服务,或者是否遇到盗用、欺诈等不法行为。这些技术还会帮助我们改进服务效率,提升登录和响应速度。</p>
-    <p class="text-content">我们可能会利用Cookie和同类技术了解您的偏好和使用习惯,进行咨询或数据分析,以改善产品服务。</p>
-    <p class="text-content">在OASISMETA绿洲平台的分享页中,我们可能会使用cookie对浏览活动进行记录,用于排查崩溃、延迟的相关异常情况以及探索更好的服务方式。</p>
-    <p class="text-content">大多数浏览器均为用户提供了清除浏览器缓存数据的功能,您可以在浏览器设置功能中进行相应的数据清除操作。如您进行清除,可能因为这些修改,您可能无法使用依赖于Cookie由公司提供的服务或相应功能。</p>
+    <p class="text-content">
+      我们可能会设置认证与保障安全性的cookie
+      或匿名标识符,使我们确认您是否安全登录服务,或者是否遇到盗用、欺诈等不法行为。这些技术还会帮助我们改进服务效率,提升登录和响应速度。
+    </p>
+    <p class="text-content">
+      我们可能会利用Cookie和同类技术了解您的偏好和使用习惯,进行咨询或数据分析,以改善产品服务。
+    </p>
+    <p class="text-content">
+      在OASISMETA绿洲平台的分享页中,我们可能会使用cookie对浏览活动进行记录,用于排查崩溃、延迟的相关异常情况以及探索更好的服务方式。
+    </p>
+    <p class="text-content">
+      大多数浏览器均为用户提供了清除浏览器缓存数据的功能,您可以在浏览器设置功能中进行相应的数据清除操作。如您进行清除,可能因为这些修改,您可能无法使用依赖于Cookie由公司提供的服务或相应功能。
+    </p>
     <h4>三、我们如何存储个人信息</h4>
     <h5>(一)信息存储的地点</h5>
     <p class="text-content">
@@ -137,18 +196,33 @@
     </p>
     <h4>四、我们如何共享、转让、公开披露个人信息</h4>
     <h5>(一)个人信息的共享、转让</h5>
-    <p class="text-content"><span class="strong-text">我们不会向第三方共享、转让您的个人信息,除非经过您本人事先授权同意,或者共享、转让的个人信息是去标识化处理后的信息,且共享第三方无法重新识别此类信息的自然人主体。</span></p>
+    <p class="text-content">
+      <span class="strong-text">我们不会向第三方共享、转让您的个人信息,除非经过您本人事先授权同意,或者共享、转让的个人信息是去标识化处理后的信息,且共享第三方无法重新识别此类信息的自然人主体。</span>
+    </p>
     <h6>1.在下列情况下,经过您的自主选择同意,我们可能会共享的个人信息</h6>
     <p class="sub-text">(1)为实现相关功能或服务与关联方及合作方共享</p>
-    <p class="text-content">a.支付功能:支付功能由与我们合作的第三方支付机构向您提供服务。第三方支付机构可能需要收集您的姓名、银行卡类型及卡号、有效期及手机号码。银行卡号、有效期是个人敏感信息,这些信息是支付功能所必需的信息,拒绝提供将导致您无法使用该功能,但不影响其他功能的正常使用。</p>
-    <p class="text-content">b.订单功能:当您使用“我的”--“订单”功能时,我们可能会与下单的相关服务提供方共享您的订单信息,以实现您向其购买商品或服务的需求,并促使其可以完成后续的服务。</p>
-    <p class="text-content">c.当您在使用OASISMETA绿洲平台中由我们的关联方、第三方提供的功能,或者当软件服务提供商、智能设备提供商、系统服务提供商与我们联合为您提供服务时我们会将实现业务所必需的信息与这些关联方、第三方共享。</p>
+    <p class="text-content">
+      a.支付功能:支付功能由与我们合作的第三方支付机构向您提供服务。第三方支付机构可能需要收集您的姓名、银行卡类型及卡号、有效期及手机号码。银行卡号、有效期是个人敏感信息,这些信息是支付功能所必需的信息,拒绝提供将导致您无法使用该功能,但不影响其他功能的正常使用。
+    </p>
+    <p class="text-content">
+      b.订单功能:当您使用“我的”--“订单”功能时,我们可能会与下单的相关服务提供方共享您的订单信息,以实现您向其购买商品或服务的需求,并促使其可以完成后续的服务。
+    </p>
+    <p class="text-content">
+      c.当您在使用OASISMETA绿洲平台中由我们的关联方、第三方提供的功能,或者当软件服务提供商、智能设备提供商、系统服务提供商与我们联合为您提供服务时我们会将实现业务所必需的信息与这些关联方、第三方共享。
+    </p>
     <!-- <p class="text-content">d.地理位置服务:当您使用地理位置相关服务时(例如附近经销商等功能),我们会将您的设备标识信息以及GPS信息与位置服务提供方(高德地图)进行共享,以便向您反馈地理位置结果。如您拒绝提供GPS信息,会影响地理位置服务功能,但不会影响其他功能正常使用。</p> -->
     <p class="sub-text">(2)帮助您参加营销推广活动</p>
-    <p class="text-content">当您选择参加我们及我们的关联方或第三方举办的有关营销活动时,根据活动可能需要您提供<span class="strong-text">姓名、通信地址、联系方式、银行账号</span>信息。<span class="strong-text">这些信息可能包括个人敏感信息(如个人电话号码)</span>,如果您拒绝提供这些信息,可能影响您参加相关活动或领取奖品,但不会影响其他功能。经过您的明示同意,我们会将上述信息与第三方共享,以保障您在联合活动中获得体验一致的服务,或委托第三方及时向您提供奖品。</p>
+    <p class="text-content">
+      当您选择参加我们及我们的关联方或第三方举办的有关营销活动时,根据活动可能需要您提供<span class="strong-text">姓名、通信地址、联系方式、银行账号</span>信息。<span
+        class="strong-text">这些信息可能包括个人敏感信息(如个人电话号码)</span>,如果您拒绝提供这些信息,可能影响您参加相关活动或领取奖品,但不会影响其他功能。经过您的明示同意,我们会将上述信息与第三方共享,以保障您在联合活动中获得体验一致的服务,或委托第三方及时向您提供奖品。
+    </p>
     <p class="sub-text">(3)实现安全与分析统计的共享信息</p>
-    <p class="text-content">a.保障使用安全:我们非常重视账号与服务安全,为保障您和其他用户的账号与财产安全,使您和我们的正当合法权益免受不法侵害,我们和服务提供商可能会共享必要的设备、账号及日志信息。</p>
-    <p class="text-content">b.分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。</p>
+    <p class="text-content">
+      a.保障使用安全:我们非常重视账号与服务安全,为保障您和其他用户的账号与财产安全,使您和我们的正当合法权益免受不法侵害,我们和服务提供商可能会共享必要的设备、账号及日志信息。
+    </p>
+    <p class="text-content">
+      b.分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。
+    </p>
     <h6>2. 共享原则</h6>
     <p class="text-content">
       <span class="strong-text">(1)授权同意原则:</span>
@@ -162,9 +236,7 @@
       <span class="strong-text">(3)安全审慎原则:</span>
       我们将审慎评估关联方、第三方数据使用共享信息的目的,对这些合作方的安全保障能力进行综合评估,并要求其遵循合作法律协议。我们会对合作方获取信息的软件工具开发包(SDK)、应用程序接口(API)进行严格的安全监测,以保护数据安全。接入第三方SDK/API情况:
     </p>
-    <p class="text-content-no-margin">
-      1) 第三方SDK名称:华为HMS推送SDK:
-    </p>
+    <p class="text-content-no-margin">1) 第三方SDK名称:华为HMS推送SDK:</p>
     <p class="text-content-no-margin">
       SDK包名:com.huawei.hms、com.huawei.agconnect
     </p>
@@ -177,7 +249,9 @@
     <p class="text-content-no-margin">
       收集个人信息类型:设备识别号等设备信息
     </p>
-    <p class="text-content-no-margin">第三方隐私政策链接:https://consumer.huawei.com/cn/privacy/privacy-policy/</p>
+    <p class="text-content-no-margin">
+      第三方隐私政策链接:https://consumer.huawei.com/cn/privacy/privacy-policy/
+    </p>
     <p class="text-content-no-margin">提供方:华为终端有限公司</p>
     <p class="text-content-no-margin">2)第三方SDK:支付宝 SDK</p>
     <p class="text-content-no-margin">
@@ -187,9 +261,7 @@
       第三方隐私政策链接:http://opendocs.alipay.com/open/01g6qm
     </p>
     <p class="text-content-no-margin">提供方:支付宝(中国)网络技术有限公司</p>
-    <p class="text-content-no-margin">
-      3)第三方SDK:微信支付 SDK
-    </p>
+    <p class="text-content-no-margin">3)第三方SDK:微信支付 SDK</p>
     <p class="text-content-no-margin">
       收集个人信息目的/用途:当您在购买平台商品或服务时,为方便您完成相关支付行为
       收集个人信息类型:微信支付授权信息、Mac地址、IMEI、Android_id、IMSI
@@ -198,78 +270,162 @@
     </p>
     <p class="text-content-no-margin">提供方:深圳市腾讯计算机系统有限公司</p>
     <p class="text-content-no-margin">4)第三方SDK:阿里云</p>
-    <p class="text-content-no-margin">收集个人信息目的/用途:提供图片、html页面、素材、视频、音频、上传文件的云存储能力、日志上传及分析、域名解析功能,身份证、营业执照等ORC识别和验证功能。</p>
-    <p class="text-content-no-margin">收集个人信息类型:手机图片、网络信息、手机运营商、系统版本,IMSI。</p>
-    <p class="text-content-no-margin">需要获取的权限:读取您的手机状态、网络状态权限、存储权限、相机、录音/视频、闪光灯权限。</p>
+    <p class="text-content-no-margin">
+      收集个人信息目的/用途:提供图片、html页面、素材、视频、音频、上传文件的云存储能力、日志上传及分析、域名解析功能,身份证、营业执照等ORC识别和验证功能。
+    </p>
+    <p class="text-content-no-margin">
+      收集个人信息类型:手机图片、网络信息、手机运营商、系统版本,IMSI。
+    </p>
+    <p class="text-content-no-margin">
+      需要获取的权限:读取您的手机状态、网络状态权限、存储权限、相机、录音/视频、闪光灯权限。
+    </p>
     <p class="text-content-no-margin">第三方隐私政策链接:</p>
-    <p class="text-content-no-margin">https://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html?spm=a2c4g.11186623.J_9220772140.90.38eca7d68mm2Y2</p>
+    <p class="text-content-no-margin">
+      https://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud201902141711_54837.html?spm=a2c4g.11186623.J_9220772140.90.38eca7d68mm2Y2
+    </p>
     <p class="text-content-no-margin">提供方:阿里云计算有限公司</p>
     <h6>3.转让</h6>
-    <p class="text-content">(1)我们不会转让您的个人信息给任何其他第三方,除非征得您的明确同意。</p>
-    <p class="text-content">2)随着我们业务的持续发展,我们将有可能进行合并、收购、资产转让,您的个人信息有可能因此而被转移。在发生前述变更时,我们将按照法律法规及不低于本隐私政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求继受方重新征得您的授权同意。</p>
+    <p class="text-content">
+      (1)我们不会转让您的个人信息给任何其他第三方,除非征得您的明确同意。
+    </p>
+    <p class="text-content">
+      2)随着我们业务的持续发展,我们将有可能进行合并、收购、资产转让,您的个人信息有可能因此而被转移。在发生前述变更时,我们将按照法律法规及不低于本隐私政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求继受方重新征得您的授权同意。
+    </p>
     <h5>(二)个人信息的公开披露</h5>
-    <p class="text-content">1.我们不会公开披露您的信息,除非遵循国家法律法规规定或者获得您的同意。 我们公开披露您的个人信息会采用符合行业内标准的安全保护措施。</p>
-    <p class="text-content"><span class="strong-text">2.对违规账号、欺诈行为进行处罚公告时,我们会披露相关账号的必要信息。</span></p>
+    <p class="text-content">
+      1.我们不会公开披露您的信息,除非遵循国家法律法规规定或者获得您的同意。
+      我们公开披露您的个人信息会采用符合行业内标准的安全保护措施。
+    </p>
+    <p class="text-content">
+      <span class="strong-text">2.对违规账号、欺诈行为进行处罚公告时,我们会披露相关账号的必要信息。</span>
+    </p>
     <p class="text-content">3.您公开发布的作品、关注将会在个人主页中展示。</p>
-    <p class="text-content">4.您参与平台组织的活动时,您的头像、昵称可能会在排行榜、中奖名单等榜单中展示。</p>
+    <p class="text-content">
+      4.您参与平台组织的活动时,您的头像、昵称可能会在排行榜、中奖名单等榜单中展示。
+    </p>
     <h5>(三)依法豁免征得同意共享、转让、公开披露的个人信息</h5>
-    <p class="text-content">请您理解,在下列情形中,根据法律法规及国家标准,我们共享、转让、公开披露您的个人信息无需征得您的授权同意:</p>
+    <p class="text-content">
+      请您理解,在下列情形中,根据法律法规及国家标准,我们共享、转让、公开披露您的个人信息无需征得您的授权同意:
+    </p>
     <p class="text-content">(1)与国家安全、国防安全直接相关的;</p>
-    <p class="text-content">(2)与公共安全、公共卫生、重大公共利益直接相关的</p>
-    <p class="text-content">(3)与犯罪侦查、起诉、审判和判决执行等直接相关的</p>
-    <p class="text-content">(4)出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的</p>
+    <p class="text-content">
+      (2)与公共安全、公共卫生、重大公共利益直接相关的
+    </p>
+    <p class="text-content">
+      (3)与犯罪侦查、起诉、审判和判决执行等直接相关的
+    </p>
+    <p class="text-content">
+      (4)出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的
+    </p>
     <p class="text-content">(5)您自行向社会公众公开的个人信息</p>
-    <p class="text-content">(6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道</p>
+    <p class="text-content">
+      (6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道
+    </p>
     <h4>五、我们如何保护个人信息安全</h4>
-    <p class="text-content">(一)我们非常重视您个人信息的安全,将努力采取合理的安全措施(包括技术方面和管理方面)来保护您的个人信息,防止您提供的个人信息被不当使用或未经授权的情况下被访问、公开披露、使用、修改、损坏、丢失或泄漏。</p>
-    <p class="text-content">(二)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。</p>
-    <p class="text-content">(三)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。</p>
-    <p class="text-content"><span class="strong-text">(四)尽管已经采取了上述合理有效措施,并已经遵守了相关法律规定要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保您提供给我们的个人信息的安全性。您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码、短信验证码等个人信息透露给他人。</span></p>
-    <p class="text-content">(五)我们会制定应急处理预案,并在发生用户信息安全事件时立即启动应急预案,努力阻止该等安全事件的影响和后果扩大。一旦发生用户信息安全事件(泄露、丢失等)后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已经采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以推送通知、邮件、信函、短信等形式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照相关监管部门要求,上报用户信息安全事件的处置情况。</p>
-    <p class="text-content"><span class="strong-text">(六)我们谨此特别提醒您,本《隐私政策》提供的个人信息保护措施仅适用于“OASISMETA绿洲平台”及相关服务。一旦您离开“OASISMETA绿洲平台”及相关服务,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在“OASISMETA绿洲平台”及相关服务之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于“OASISMETA绿洲平台”的链接或引导。</span></p>
+    <p class="text-content">
+      (一)我们非常重视您个人信息的安全,将努力采取合理的安全措施(包括技术方面和管理方面)来保护您的个人信息,防止您提供的个人信息被不当使用或未经授权的情况下被访问、公开披露、使用、修改、损坏、丢失或泄漏。
+    </p>
+    <p class="text-content">
+      (二)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
+    </p>
+    <p class="text-content">
+      (三)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
+    </p>
+    <p class="text-content">
+      <span
+        class="strong-text">(四)尽管已经采取了上述合理有效措施,并已经遵守了相关法律规定要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保您提供给我们的个人信息的安全性。您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码、短信验证码等个人信息透露给他人。</span>
+    </p>
+    <p class="text-content">
+      (五)我们会制定应急处理预案,并在发生用户信息安全事件时立即启动应急预案,努力阻止该等安全事件的影响和后果扩大。一旦发生用户信息安全事件(泄露、丢失等)后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已经采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以推送通知、邮件、信函、短信等形式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照相关监管部门要求,上报用户信息安全事件的处置情况。
+    </p>
+    <p class="text-content">
+      <span
+        class="strong-text">(六)我们谨此特别提醒您,本《隐私政策》提供的个人信息保护措施仅适用于“OASISMETA绿洲平台”及相关服务。一旦您离开“OASISMETA绿洲平台”及相关服务,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在“OASISMETA绿洲平台”及相关服务之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于“OASISMETA绿洲平台”的链接或引导。</span>
+    </p>
     <h4>六、您的权利</h4>
-    <p class="text-content">我们非常重视您对个人信息的管理,并尽全力保护您对于您个人信息的查询、访问、修改、删除、撤回同意授权、注销账号、投诉举报以及设置隐私功能等权利,以使您拥有充分的能力保障您的隐私和安全。</p>
+    <p class="text-content">
+      我们非常重视您对个人信息的管理,并尽全力保护您对于您个人信息的查询、访问、修改、删除、撤回同意授权、注销账号、投诉举报以及设置隐私功能等权利,以使您拥有充分的能力保障您的隐私和安全。
+    </p>
     <h5>(一)访问、删除、更正您的个人信息</h5>
     <p class="text-content">您可以通过以下方式管理您的信息:</p>
     <h6>1.访问个人账号信息:</h6>
-    <p class="text-content">您可以查询、访问、更正您的头像、用户名、简介等基本信息,您可以在OASISMETA绿洲平台的“我的”-“个人信息”-“详情”中进行查询、编辑。</p>
+    <p class="text-content">
+      您可以查询、访问、更正您的头像、用户名、简介等基本信息,您可以在OASISMETA绿洲平台的“我的”-“个人信息”-“详情”中进行查询、编辑。
+    </p>
     <h6>2 加密商品存放</h6>
-    <p class="text-content"><span class="strong-text">您可通过“柜子”查询我发布的、我持有的、我上架的加密商品。</span></p>
+    <p class="text-content">
+      <span class="strong-text">您可通过“柜子”查询我发布的、我持有的、我上架的加密商品。</span>
+    </p>
     <h5>(二)消息提醒</h5>
-    <p class="text-content"><span class="strong-text">平台内会推送特定消息,包括流转、赠送、获得加密商品,用户信息更新等有限提醒。</span></p>
+    <p class="text-content">
+      <span class="strong-text">平台内会推送特定消息,包括流转、赠送、获得加密商品,用户信息更新等有限提醒。</span>
+    </p>
     <h5>(三)改变您授权同意范围或撤销授权</h5>
-    <p class="text-content">您可以在设备本身操作系统中关闭相关权限改变同意范围或撤回您的授权。撤回授权后我们将不再收集与这些权限相关信息。</p>
-    <p class="text-content"><span class="strong-text">请您理解,特定的业务功能和服务将需要您的信息才能得以完成,当您撤回同意或授权后,我们无法继续为您提供撤回同意或授权所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意或授权的决定,不会影响公司此前基于您的授权而开展的个人信息处理。</span></p>
+    <p class="text-content">
+      您可以在设备本身操作系统中关闭相关权限改变同意范围或撤回您的授权。撤回授权后我们将不再收集与这些权限相关信息。
+    </p>
+    <p class="text-content">
+      <span
+        class="strong-text">请您理解,特定的业务功能和服务将需要您的信息才能得以完成,当您撤回同意或授权后,我们无法继续为您提供撤回同意或授权所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意或授权的决定,不会影响公司此前基于您的授权而开展的个人信息处理。</span>
+    </p>
     <h5>(四)注销您的账号</h5>
-    <p class="text-content">您可以在“OASISMETA绿洲平台”客户端“点击“我的”-“设置”-“账号注销”申请注销账号。有关注销的流程和内容,请参见《账号注销须知》。在您注销账号前,我们将验证您的个人身份、安全状态、设备信息等。您知悉并理解,注销账号的行为是不可逆的行为,当您注销账号后,我们将删除有关您的相关信息或进行匿名化处理,但法律法规另有规定的除外。</p>
+    <p class="text-content">
+      您可以在“OASISMETA绿洲平台”客户端“点击“我的”-“设置”-“账号注销”申请注销账号。有关注销的流程和内容,请参见《账号注销须知》。在您注销账号前,我们将验证您的个人身份、安全状态、设备信息等。您知悉并理解,注销账号的行为是不可逆的行为,当您注销账号后,我们将删除有关您的相关信息或进行匿名化处理,但法律法规另有规定的除外。
+    </p>
     <h5>(五)投诉举报</h5>
-    <p class="text-content">如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索(例如:认为我们收集您的个人信息违反法律规定或者双方约定),您可以通过“我的”-“用户反馈”页面与我们联系。我们核查后会及时反馈您的投诉与举报。</p>
+    <p class="text-content">
+      如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索(例如:认为我们收集您的个人信息违反法律规定或者双方约定),您可以通过“我的”-“用户反馈”页面与我们联系。我们核查后会及时反馈您的投诉与举报。
+    </p>
     <h5>(六)访问隐私政策</h5>
-    <p class="text-content">您可以在注册页面,或者在登录个人账号“我的-设置”页面查看本《隐私政策》的全部内容或通过OASISMETA绿洲平台网页端首页查看本《隐私政策》全部内容。</p>
+    <p class="text-content">
+      您可以在注册页面,或者在登录个人账号“我的-设置”页面查看本《隐私政策》的全部内容或通过OASISMETA绿洲平台网页端首页查看本《隐私政策》全部内容。
+    </p>
     <h5>(七)停止运营向您告知</h5>
-    <p class="text-content"><span class="strong-text">如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理。</span></p>
+    <p class="text-content">
+      <span class="strong-text">如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理。</span>
+    </p>
     <h4>七、未成年人条款</h4>
-    <p class="text-content">若您是未满18周岁的未成年人,在使用“OASISMETA绿洲平台”及相关服务前,应在您的父母或其他监护人监护、指导下共同阅读并同意本《隐私政策》。我们根据国家相关法律法规的规定保护未成年人的个人信息,只会在法律允许、父母或其他监护人明确同意或保护未成年人所必要的情况下收集、使用、储存、共享、转让或披露未成年人的个人信息;如果我们发现在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关信息。若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本《隐私政策》公示的联系方式与我们联系。</p>
+    <p class="text-content">
+      若您是未满18周岁的未成年人,在使用“OASISMETA绿洲平台”及相关服务前,应在您的父母或其他监护人监护、指导下共同阅读并同意本《隐私政策》。我们根据国家相关法律法规的规定保护未成年人的个人信息,只会在法律允许、父母或其他监护人明确同意或保护未成年人所必要的情况下收集、使用、储存、共享、转让或披露未成年人的个人信息;如果我们发现在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关信息。若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本《隐私政策》公示的联系方式与我们联系。
+    </p>
     <h4>八、隐私政策的修订和通知</h4>
-    <p class="text-content">(一)为给您提供更好的服务,“OASISMETA绿洲平台”及相关服务将不时更新与变化,我们会适时对本《隐私政策》进行修订,这些修订构成本《隐私政策》的一部分并具有等同于本《隐私政策》的效力,未经您明确同意,我们不会削减您依据当前生效的《隐私政策》所应享受的权利。</p>
-    <p class="text-content">(二)本《隐私政策》更新后,我们会在“OASISMETA绿洲平台”发出更新版本,并在更新后的条款生效前通过官方网站公告或其他适当的方式提醒您更新的内容,以便您及时了解本《隐私政策》的最新版本。</p>
+    <p class="text-content">
+      (一)为给您提供更好的服务,“OASISMETA绿洲平台”及相关服务将不时更新与变化,我们会适时对本《隐私政策》进行修订,这些修订构成本《隐私政策》的一部分并具有等同于本《隐私政策》的效力,未经您明确同意,我们不会削减您依据当前生效的《隐私政策》所应享受的权利。
+    </p>
+    <p class="text-content">
+      (二)本《隐私政策》更新后,我们会在“OASISMETA绿洲平台”发出更新版本,并在更新后的条款生效前通过官方网站公告或其他适当的方式提醒您更新的内容,以便您及时了解本《隐私政策》的最新版本。
+    </p>
     <h4>九、适用范围</h4>
     <p class="text-content">
-      本《隐私政策》适用于由OASISMETA绿洲平台运营主体提供的所有服务,除本《隐私政策》另有规定外,本《隐私政策》所用词语与《OASISMETA绿洲平台用户协议》所定义的词语具有相同的涵义。<span class="strong-text">本《隐私政策》不适用于:</span>
+      本《隐私政策》适用于由OASISMETA绿洲平台运营主体提供的所有服务,除本《隐私政策》另有规定外,本《隐私政策》所用词语与《OASISMETA绿洲平台用户协议》所定义的词语具有相同的涵义。<span
+        class="strong-text">本《隐私政策》不适用于:</span>
     </p>
+    <p class="text-content">1.其他第三方产品或服务</p>
     <p class="text-content">
-      1.其他第三方产品或服务
+      2.为“OASISMETA绿洲平台”服务进行广告宣传的其他第三方
     </p>
-    <p class="text-content">2.为“OASISMETA绿洲平台”服务进行广告宣传的其他第三方</p>
     <p class="text-content">
-      <span class="strong-text">您使用这些第三方服务(包括您向这些第三方提供的任何个人信息),将受这些第三方的服务条款及隐私政策约束(而非本《隐私政策》),具体规定请您仔细阅读第三方的条款。请您妥善保护自己的个人信息,仅在必要的情况下向第三方提供。</span>
+      <span
+        class="strong-text">您使用这些第三方服务(包括您向这些第三方提供的任何个人信息),将受这些第三方的服务条款及隐私政策约束(而非本《隐私政策》),具体规定请您仔细阅读第三方的条款。请您妥善保护自己的个人信息,仅在必要的情况下向第三方提供。</span>
     </p>
     <p class="text-content">
-      <span class="strong-text">3.请您了解,本《隐私政策》中所述的“OASISMETA绿洲平台”及相关服务可能会根据您所使用的手机型号、系统版本、软件应用程序版本、移动客户端等因素而有所不同。最终的产品和服务以您所使用的“OASISMETA绿洲平台”及相关服务为准。</span>
+      <span
+        class="strong-text">3.请您了解,本《隐私政策》中所述的“OASISMETA绿洲平台”及相关服务可能会根据您所使用的手机型号、系统版本、软件应用程序版本、移动客户端等因素而有所不同。最终的产品和服务以您所使用的“OASISMETA绿洲平台”及相关服务为准。</span>
     </p>
     <h4>十、其他</h4>
-    <p class="text-content">1.如果您对个人信息保护问题有投诉、建议、疑问,您可以将问题发送至(assistant@raex.vip)</p>
-    <p class="text-content">我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。</p>
+    <p class="text-content">
+      1.如果您对个人信息保护问题有投诉、建议、疑问,您可以将问题发送至(assistant@raex.vip)
+    </p>
+    <p class="text-content">
+      我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。
+    </p>
   </div>
+</body>
+<div style="all: initial">
+  <div id="__hcfy__" style="all: initial"></div>
+</div>
+<div style="all: initial">
+  <div style="all: initial"></div>
+</div>
 
-</body><div style="all: initial;"><div id="__hcfy__" style="all: initial;"></div></div><div style="all: initial;"><div style="all: initial;"></div></div></html>
+</html>

+ 42 - 1
src/main/vue/src/router.js

@@ -1256,6 +1256,15 @@ const router = new Router({
                         title: '公屏对话'
                     }
                 },
+                {
+                    path: '/livePublicScreenChatList',
+                    name: 'LivePublicScreenChatList',
+                    component: () =>
+                        import(/* webpackChunkName: "livePublicScreenChatList" */ '@/views/LivePublicScreenChatList.vue'),
+                    meta: {
+                        title: '直播聊天内容管理'
+                    }
+                },
                 {
                     path: '/metaItemEdit',
                     name: 'MetaItemEdit',
@@ -1436,6 +1445,38 @@ const router = new Router({
                         title: '易拍邀请',
                     },
                 },
+                {
+                    path: '/metaSpatialWharfList',
+                    name: 'MetaSpatialWharfList',
+                    component: () => import(/* webpackChunkName: "metaSpatialWharfList" */ '@/views/MetaSpatialWharfList.vue'),
+                    meta: {
+                       title: '船只停靠列表',
+                    },
+               },
+                {
+                    path: '/metaBoatPositionEdit',
+                    name: 'MetaBoatPositionEdit',
+                    component: () => import(/* webpackChunkName: "metaBoatPositionEdit" */ '@/views/MetaBoatPositionEdit.vue'),
+                    meta: {
+                       title: '空间船位管理编辑',
+                    },
+                },
+                {
+                    path: '/metaBoatPositionList',
+                    name: 'MetaBoatPositionList',
+                    component: () => import(/* webpackChunkName: "metaBoatPositionList" */ '@/views/MetaBoatPositionList.vue'),
+                    meta: {
+                       title: '空间船位管理',
+                    },
+               },
+                {
+                    path: '/metaVisitorList',
+                    name: 'MetaVisitorList',
+                    component: () => import(/* webpackChunkName: "metaVisitorList" */ '@/views/MetaVisitorList.vue'),
+                    meta: {
+                       title: '游客管理',
+                    },
+                },
                 {
                     path: '/neteaseUserList',
                     name: 'NeteaseUserList',
@@ -1535,4 +1576,4 @@ router.beforeEach((to, from, next) => {
     }
 });
 
-export default router;
+export default router;

+ 165 - 0
src/main/vue/src/views/LivePublicScreenChatList.vue

@@ -0,0 +1,165 @@
+<template>
+	<div class="list-view">
+		<page-title>
+			<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="nickname" align="center" label="用户昵称"> </el-table-column>
+			<el-table-column prop="userId" align="center" label="用户id"> </el-table-column>
+			<el-table-column prop="avatar" align="center" label="头像">
+				<template slot-scope="{ row }">
+					<el-image
+						style="width: 30px; height: 30px"
+						:src="row.avatar"
+						fit="cover"
+						:preview-src-list="[row.avatar]"
+					>
+					</el-image>
+				</template>
+			</el-table-column>
+			<el-table-column prop="messageInfo" align="center" width="600" label="消息内容"> </el-table-column>
+			<el-table-column prop="illegal" align="center" label="是否合法">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.illegal ? '' : 'info'"> {{ row.illegal }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="recall" align="center" label="是否撤回">
+				<template v-slot="{ row }">
+                    <template v-if="row.recall === 2">
+                        {{ '待撤回' }}
+                    </template>
+					<template v-else-if="row.recall === 3">
+                        {{ '已撤回' }}
+                    </template>
+                    <template v-else>
+                        {{ '正常' }}
+                    </template>
+                </template>
+            </el-table-column>
+			<el-table-column prop="time" align="center" width="200" label="消息发送时间"> </el-table-column>
+			<el-table-column label="操作" align="center" fixed="right" width="100">
+                <template slot-scope="{ row }">
+                    <el-button @click="recall(row)" type="danger" size="mini" plain v-if="row.recall === 1">撤回</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>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+	name: 'PublicScreenChatList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			multipleMode: false,
+			search: '',
+			url: '/publicScreenChat/all',
+			downloading: false
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		beforeGetData() {
+			return { search: this.search, query: { del: false, type: 2 } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/publicScreenChat/excel', {
+					responseType: 'blob',
+					params: { size: 10000 ,query: { del: false }},
+				})
+				.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);
+				});
+		},
+		recall(row) {
+			this.$alert('确定要将该信息撤回吗?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/publicScreenChat/recall/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('操作成功,等待服务器撤回');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		}
+	}
+};
+</script>
+<style lang="less" scoped>
+
+</style>

+ 175 - 175
src/main/vue/src/views/MetaAccessoriesEdit.vue

@@ -1,183 +1,183 @@
 <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="purchaseMethod" label="购买方式">
-						<el-select
-							v-model="formData.purchaseMethod"
-							clearable
-							filterable
-							placeholder="请选择"
-							@change="changePurchaseMethod()"
-						>
-							<el-option
-								v-for="item in purchaseMethodOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<el-form-item
-						prop="price"
-						label="金币数量"
-						v-if="formData.purchaseMethod && formData.purchaseMethod === 'GOLD'"
-					>
-						<el-input-number type="price" v-model="formData.price" :step="1" :min="1"> </el-input-number>
-						<div class="tip">输入规则:正整数,最小为1</div>
-					</el-form-item>
-					<el-form-item
-						prop="collectionName"
-						label="NFT名称"
-						v-if="formData.purchaseMethod && formData.purchaseMethod === 'NFT'"
-					>
-						<el-input v-model="formData.collectionName"> </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="name" label="配饰名称">
+                        <el-input v-model="formData.name"> </el-input>
+                    </el-form-item>
+                    <el-form-item prop="purchaseMethod" label="购买方式">
+                        <el-select
+                            v-model="formData.purchaseMethod"
+                            clearable
+                            filterable
+                            placeholder="请选择"
+                            @change="changePurchaseMethod()"
+                        >
+                            <el-option
+                                v-for="item in purchaseMethodOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item
+                        prop="price"
+                        label="金币数量"
+                        v-if="formData.purchaseMethod && formData.purchaseMethod === 'GOLD'"
+                    >
+                        <el-input-number type="price" v-model="formData.price" :step="1" :min="1"> </el-input-number>
+                        <div class="tip">输入规则:正整数,最小为1</div>
+                    </el-form-item>
+                    <el-form-item
+                        prop="collectionName"
+                        label="NFT名称"
+                        v-if="formData.purchaseMethod && formData.purchaseMethod === 'NFT'"
+                    >
+                        <el-input v-model="formData.collectionName"> </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>
 <script>
 export default {
-	name: 'MetaAccessoriesEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaAccessories/get/' + this.$route.query.id)
-				.then(res => {
-					this.formData = res;
-				})
-				.catch(e => {
-					console.log(e);
-					this.$message.error(e.error);
-				});
-		}
-	},
-	data() {
-		return {
-			reg: /^[1-9]\d*$/,
-			saving: false,
-			formData: {},
-			rules: {
-				name: [
-					{
-						required: true,
-						message: '请输入配饰名称',
-						trigger: 'blur'
-					}
-				],
-				purchaseMethod: [
-					{
-						required: true,
-						message: '请输入购买方式',
-						trigger: 'blur'
-					}
-				],
-				price: [
-					{
-						required: true,
-						message: '请输入所需金币数量',
-						trigger: 'blur'
-					},
-					{
-						validator: (rule, value, callback) => {
-							if (!this.reg.test(value)) {
-								callback(new Error('金币数量必须为大于1的整数'));
-								return;
-							} else {
-								callback();
-							}
-						}
-					}
-				],
-				collectionName: [
-					{
-						required: true,
-						message: '请输入NFT名称',
-						trigger: 'blur'
-					}
-				]
-			},
-			purchaseMethodOptions: [
-				{ label: 'NFT', value: 'NFT' },
-				{ label: '金币', value: 'GOLD' }
-			]
-		};
-	},
-	methods: {
-		changePurchaseMethod() {
-			this.$delete(this.formData, 'price');
-			this.$delete(this.formData, 'collectionName');
-		},
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+    name: 'MetaAccessoriesEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaAccessories/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            reg: /^[1-9]\d*$/,
+            saving: false,
+            formData: {},
+            rules: {
+                name: [
+                    {
+                        required: true,
+                        message: '请输入配饰名称',
+                        trigger: 'blur'
+                    }
+                ],
+                purchaseMethod: [
+                    {
+                        required: true,
+                        message: '请输入购买方式',
+                        trigger: 'blur'
+                    }
+                ],
+                price: [
+                    {
+                        required: true,
+                        message: '请输入所需金币数量',
+                        trigger: 'blur'
+                    },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!this.reg.test(value)) {
+                                callback(new Error('金币数量必须为大于1的整数'));
+                                return;
+                            } else {
+                                callback();
+                            }
+                        }
+                    }
+                ],
+                collectionName: [
+                    {
+                        required: true,
+                        message: '请输入NFT名称',
+                        trigger: 'blur'
+                    }
+                ]
+            },
+            purchaseMethodOptions: [
+                { label: 'NFT', value: 'NFT' },
+                { label: '金币', value: 'GOLD' }
+            ]
+        };
+    },
+    methods: {
+        changePurchaseMethod() {
+            this.$delete(this.formData, 'price');
+            this.$delete(this.formData, 'collectionName');
+        },
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
 
-			this.saving = true;
-			this.$http
-				.post('/metaAccessories/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(`/metaAccessories/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('/metaAccessories/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(`/metaAccessories/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>

+ 173 - 173
src/main/vue/src/views/MetaAccessoriesList.vue

@@ -1,63 +1,63 @@
 <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" align="center" label="ID" width="100"> </el-table-column>
-			<el-table-column prop="name" align="center" label="配饰名称"> </el-table-column>
-			<el-table-column prop="purchaseMethod" align="center" label="购买方式" :formatter="purchaseMethodFormatter">
-			</el-table-column>
-			<el-table-column prop="price" align="center" label="金币数量"> </el-table-column>
-			<el-table-column prop="collectionName" align="center" label="NFT名称"> </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">
+    <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="name" align="center" label="配饰名称"> </el-table-column>
+            <el-table-column prop="purchaseMethod" align="center" label="购买方式" :formatter="purchaseMethodFormatter">
+            </el-table-column>
+            <el-table-column prop="price" align="center" label="金币数量"> </el-table-column>
+            <el-table-column prop="collectionName" align="center" label="NFT名称"> </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>
@@ -65,126 +65,126 @@
                     <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-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: 'MetaAccessoriesList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaAccessories/all',
-			downloading: false,
-			purchaseMethodOptions: [
-				{ label: 'NFT', value: 'NFT' },
-				{ label: '金币', value: 'GOLD' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		purchaseMethodFormatter(row, column, cellValue, index) {
-			let selectedOption = this.purchaseMethodOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaAccessoriesEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaAccessoriesEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaAccessories/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(`/metaAccessories/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaAccessoriesList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaAccessories/all',
+            downloading: false,
+            purchaseMethodOptions: [
+                { label: 'NFT', value: 'NFT' },
+                { label: '金币', value: 'GOLD' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        purchaseMethodFormatter(row, column, cellValue, index) {
+            let selectedOption = this.purchaseMethodOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaAccessoriesEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaAccessoriesEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaAccessories/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaAccessories/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 125 - 125
src/main/vue/src/views/MetaAdvertRecordEdit.vue

@@ -1,134 +1,134 @@
 <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="82px"
-					label-position="right"
-					size="small"
-					style="max-width: 500px"
-				>
-					<el-form-item prop="pic" label="图片">
-						<single-upload v-model="formData.pic"> </single-upload>
-					</el-form-item>
-					<el-form-item prop="link" label="地址">
-						<el-input v-model="formData.link"> </el-input>
-					</el-form-item>
-					<el-form-item prop="application" label="用途">
-						<el-input-number type="application" v-model="formData.application"> </el-input-number>
-					</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>
+    <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="82px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px"
+                >
+                    <el-form-item prop="pic" label="图片">
+                        <single-upload v-model="formData.pic"> </single-upload>
+                    </el-form-item>
+                    <el-form-item prop="link" label="地址">
+                        <el-input v-model="formData.link"> </el-input>
+                    </el-form-item>
+                    <el-form-item prop="application" label="用途">
+                        <el-input-number type="application" v-model="formData.application"> </el-input-number>
+                    </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: 'MetaAdvertRecordEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaAdvertRecord/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: {
-				pic: [
-					{
-						required: true,
-						message: '请输入图片',
-						trigger: 'blur'
-					}
-				],
-				link: [
-					{
-						required: true,
-						message: '请输入地址',
-						trigger: 'blur'
-					}
-				],
+    name: 'MetaAdvertRecordEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaAdvertRecord/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: {
+                pic: [
+                    {
+                        required: true,
+                        message: '请输入图片',
+                        trigger: 'blur'
+                    }
+                ],
+                link: [
+                    {
+                        required: true,
+                        message: '请输入地址',
+                        trigger: 'blur'
+                    }
+                ],
                 application: [
-					{
-						required: true,
-						message: '请输入用途',
-						trigger: 'blur'
-					}
-				]
-			}
-		};
-	},
-	methods: {
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+                    {
+                        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('/metaAdvertRecord/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(`/metaAdvertRecord/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('/metaAdvertRecord/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(`/metaAdvertRecord/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>

+ 156 - 156
src/main/vue/src/views/MetaAdvertRecordList.vue

@@ -1,167 +1,167 @@
 <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>
-		</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="createdAt" label="时间"> </el-table-column>
-			<el-table-column prop="pic" label="图片">
-				<template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.pic"
-						fit="cover"
-						:preview-src-list="[row.pic]"
-					>
-					</el-image>
-				</template>
-			</el-table-column>
-			<el-table-column prop="link" label="链接地址"> </el-table-column>
+    <div class="list-view">
+        <page-title>
+            <el-button
+                @click="addRow"
+                type="primary"
+                icon="el-icon-plus"
+                :disabled="fetchingData || downloading"
+                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="createdAt" label="时间"> </el-table-column>
+            <el-table-column prop="pic" label="图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.pic"
+                        fit="cover"
+                        :preview-src-list="[row.pic]"
+                    >
+                    </el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="link" label="链接地址"> </el-table-column>
             <el-table-column prop="application" label="用途"> </el-table-column>
-			<el-table-column prop="publish" 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">
-			<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 prop="publish" 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">
+            <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: 'MetaAdvertRecordList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaAdvertRecord/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: '/metaAdvertRecordEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaAdvertRecordEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaAdvertRecord/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaAdvertRecord/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaAdvertRecordList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaAdvertRecord/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: '/metaAdvertRecordEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaAdvertRecordEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaAdvertRecord/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaAdvertRecord/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 193 - 0
src/main/vue/src/views/MetaBoatPositionEdit.vue

@@ -0,0 +1,193 @@
+<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="type" label="岛屿类型">
+						<el-select v-model="formData.type" clearable filterable placeholder="请选择">
+							<el-option
+								v-for="item in typeOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item prop="boatPos" label="位置信息">
+						<el-input v-model="formData.boatPos.x" placeholder="请输入位置信息 -> x"> </el-input>
+						<el-input v-model="formData.boatPos.y" placeholder="请输入位置信息 -> y"> </el-input>
+						<el-input v-model="formData.boatPos.z" placeholder="请输入位置信息 -> z"> </el-input>
+					</el-form-item>
+					<el-form-item prop="boatRot" label="旋转值">
+						<el-input v-model="formData.boatRot.x" placeholder="请输入旋转值 -> x"> </el-input>
+						<el-input v-model="formData.boatRot.y" placeholder="请输入旋转值 -> x"> </el-input>
+						<el-input v-model="formData.boatRot.z" placeholder="请输入旋转值 -> x"> </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>
+<script>
+export default {
+	name: 'MetaBoatPositionEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaBoatPosition/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: {
+				boatPos: {
+					x: '',
+					y: '',
+					z: ''
+				},
+				boatRot: {
+					x: '',
+					y: '',
+					z: ''
+				}
+			},
+			typeOptions: [
+				{ label: '10000m²空间岛', value: 'TEN_THOUSAND' },
+				{ label: '60000m²空间岛', value: 'SIX_THOUSAND' },
+				{ label: '90000m²空间岛', value: 'NINE_THOUSAND' }
+			],
+			rules: {
+				isLandId: [
+					{
+						required: true,
+						message: '请输入岛屿ID',
+						trigger: 'blur'
+					}
+				],
+				boatPos: [
+					{
+						required: true,
+						message: '请输入位置相关信息',
+						trigger: 'blur'
+					},
+					{
+						validator: (rule, value, callback) => {
+							if (value.x === null || value.x === undefined || value.x === '') {
+								callback(new Error('请输入位置信息 -> x'));
+								return;
+							} else if (value.y === null || value.y === undefined || value.y === '') {
+								callback(new Error('请输入位置信息 -> y'));
+								return;
+							} else if (value.z === null || value.z === undefined || value.z === '') {
+								callback(new Error('请输入位置信息 -> z'));
+								return;
+							} else {
+								callback();
+							}
+						}
+					}
+				],
+				boatRot: [
+					{
+						required: true,
+						message: '请输入旋转值相关信息',
+						trigger: 'blur'
+					},
+					{
+						validator: (rule, value, callback) => {
+							if (value.x === null || value.x === undefined || value.x === '') {
+								callback(new Error('请输入旋转值 -> x'));
+								return;
+							} else if (value.y === null || value.y === undefined || value.y === '') {
+								callback(new Error('请输入旋转值 -> y'));
+								return;
+							} else if (value.z === null || value.z === undefined || value.z === '') {
+								callback(new Error('请输入旋转值 -> z'));
+								return;
+							} else {
+								callback();
+							}
+						}
+					}
+				]
+			}
+		};
+	},
+	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('/metaBoatPosition/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(`/metaBoatPosition/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/MetaBoatPositionList.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" align="center" label="船位ID" width="100"> </el-table-column>
+			<el-table-column prop="type" align="center" label="岛屿类型" :formatter="typeFormatter"> </el-table-column>
+			<el-table-column align="center" prop="boatPos" label="位置信息">
+				<template slot-scope="{ row }">
+					{{ 'x=' + row.boatPos.x + ' , ' + 'y=' + row.boatPos.y + ' , ' + 'z=' + row.boatPos.z }}
+				</template>
+			</el-table-column>
+			<el-table-column align="center" prop="boatRot" label="旋转值">
+				<template slot-scope="{ row }">
+					{{ 'x=' + row.boatRot.x + ' , ' + 'y=' + row.boatRot.y + ' , ' + 'z=' + row.boatRot.z }}
+				</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">
+			<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: 'MetaBoatPositionList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			multipleMode: false,
+			search: '',
+			url: '/metaBoatPosition/all',
+			downloading: false,
+			typeOptions: [
+				{ label: '10000m²空间岛', value: 'TEN_THOUSAND' },
+				{ label: '60000m²空间岛', value: 'SIX_THOUSAND' },
+				{ label: '90000m²空间岛', value: 'NINE_THOUSAND' }
+			]
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		typeFormatter(row, column, cellValue, index) {
+			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+			if (selectedOption) {
+				return selectedOption.label;
+			}
+			return '';
+		},
+		beforeGetData() {
+			return { search: this.search, query: { del: false } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		addRow() {
+			this.$router.push({
+				path: '/metaBoatPositionEdit',
+				query: {
+					...this.$route.query
+				}
+			});
+		},
+		editRow(row) {
+			this.$router.push({
+				path: '/metaBoatPositionEdit',
+				query: {
+					id: row.id
+				}
+			});
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaBoatPosition/excel', {
+					responseType: 'blob',
+					params: { size: 10000, query: { del: false } }
+				})
+				.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(`/metaBoatPosition/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>

+ 89 - 88
src/main/vue/src/views/MetaBonusSceneList.vue

@@ -1,99 +1,100 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<el-button
-				@click="download"
-				icon="el-icon-upload2"
-				:loading="downloading"
-				:disabled="fetchingData"
-				class="filter-item"
-			>
-				导出
-			</el-button>
-		</page-title>
-		<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="userId" label="userId"> </el-table-column>
-			<el-table-column prop="num" label="触发彩蛋个数"> </el-table-column>
-			<el-table-column prop="createdAt" label="触发时间"> </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>
+    <div class="list-view">
+        <page-title>
+            <el-button
+                @click="download"
+                icon="el-icon-upload2"
+                :loading="downloading"
+                :disabled="fetchingData"
+                class="filter-item"
+            >
+                导出
+            </el-button>
+        </page-title>
+        <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="userId" label="userId"> </el-table-column>
+            <el-table-column prop="num" label="触发彩蛋个数"> </el-table-column>
+            <el-table-column prop="createdAt" label="触发时间"> </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaBonusSceneList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			url: '/metaBonusScene/all',
-			downloading: false
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaBonusScene/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);
-				});
-		}
-	}
+    name: 'MetaBonusSceneList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            url: '/metaBonusScene/all',
+            downloading: false
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaBonusScene/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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>
+
 </style>

+ 231 - 231
src/main/vue/src/views/MetaDestroyActivityEdit.vue

@@ -1,246 +1,246 @@
 <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="120px"
-                    label-position="right"
-                    size="small"
-                    style="max-width: 500px"
-                >
-                    <el-form-item prop="audit" label="是否需要审核">
-                        <el-radio-group v-model="formData.audit">
-                            <el-radio :label="true"> 人工审核 </el-radio>
-                            <el-radio :label="false"> 自动匹配 </el-radio>
-                        </el-radio-group>
-                    </el-form-item>
-                    <el-form-item prop="collectionName" label="藏品名称" v-if="formData.audit === true">
-                        <el-input v-model="formData.collectionName" :disabled="!canEdit" class="width"> </el-input>
-                    </el-form-item>
-                    <el-form-item prop="rule" label="匹配规则设置" v-if="formData.audit === false">
-                        <template v-if="formData.rule && formData.rule.and">
-                            <div v-for="(item, i) in formData.rule.and" class="rule-item">
-                                <el-select v-model="item.detail.tag" value-key="id" size="mini">
-                                    <el-option v-for="item in tags" :key="item.id" :value="item" :label="item.name">
-                                    </el-option>
-                                </el-select>
-                                <span style="padding: 0 10px; color: #606266; font-weight: bold"> ×&nbsp;1 </span>
-                                <i @click="delRule(i)" class="el-icon-delete icon-del"> </i>
-                            </div>
-                        </template>
-                        <el-button size="mini" @click="addRule"> 添加 </el-button>
-                    </el-form-item>
-                    <el-form-item prop="num" label="藏品数量">
-                        <el-input-number
-                            type="number"
-                            v-model="formData.num"
-                            :disabled="!canEdit"
-                            :step="1"
-                            :min="0"
-                            class="width1"
-                        >
-                        </el-input-number>
-                        <div class="tip">0表示不限</div>
-                    </el-form-item>
-                    <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
-                        <el-input
-                            v-model="formData.detail"
-                            type="textarea"
-                            :autosize="{ minRows: 3, maxRows: 20 }"
-                            placeholder="请输入详情"
-                        >
-                        </el-input>
-                    </el-form-item>
-                    <el-form-item prop="awardPic" label="奖励图片">
-                        <single-upload v-model="formData.awardPic"> </single-upload>
-                    </el-form-item>
-                    <el-form-item prop="application" label="用途">
-                        <el-input-number type="application" v-model="formData.application"> </el-input-number>
-                    </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>
+	<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="120px"
+					label-position="right"
+					size="small"
+					style="max-width: 500px"
+				>
+					<el-form-item prop="audit" label="是否需要审核">
+						<el-radio-group v-model="formData.audit">
+							<el-radio :label="true"> 人工审核 </el-radio>
+							<el-radio :label="false"> 自动匹配 </el-radio>
+						</el-radio-group>
+					</el-form-item>
+					<el-form-item prop="collectionName" label="藏品名称" v-if="formData.audit === true">
+						<el-input v-model="formData.collectionName" :disabled="!canEdit" class="width"> </el-input>
+					</el-form-item>
+					<el-form-item prop="rule" label="匹配规则设置" v-if="formData.audit === false">
+						<template v-if="formData.rule && formData.rule.and">
+							<div v-for="(item, i) in formData.rule.and" class="rule-item">
+								<el-select v-model="item.detail.tag" value-key="id" size="mini">
+									<el-option v-for="item in tags" :key="item.id" :value="item" :label="item.name">
+									</el-option>
+								</el-select>
+								<span style="padding: 0 10px; color: #606266; font-weight: bold"> ×&nbsp;1 </span>
+								<i @click="delRule(i)" class="el-icon-delete icon-del"> </i>
+							</div>
+						</template>
+						<el-button size="mini" @click="addRule"> 添加 </el-button>
+					</el-form-item>
+					<el-form-item prop="num" label="藏品数量">
+						<el-input-number
+							type="number"
+							v-model="formData.num"
+							:disabled="!canEdit"
+							:step="1"
+							:min="0"
+							class="width1"
+						>
+						</el-input-number>
+						<div class="tip">0表示不限</div>
+					</el-form-item>
+					<el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
+						<el-input
+							v-model="formData.detail"
+							type="textarea"
+							:autosize="{ minRows: 3, maxRows: 20 }"
+							placeholder="请输入详情"
+						>
+						</el-input>
+					</el-form-item>
+					<el-form-item prop="awardPic" label="奖励图片">
+						<single-upload v-model="formData.awardPic"> </single-upload>
+					</el-form-item>
+					<el-form-item prop="application" label="用途">
+						<el-input-number type="application" v-model="formData.application"> </el-input-number>
+					</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: 'MetaDestroyActivityEdit',
-    created() {
-        if (this.$route.query.id) {
-            this.$http
-                .get('metaDestroyActivity/get/' + this.$route.query.id)
-                .then(res => {
-                    this.formData = res;
-                })
-                .catch(e => {
-                    console.log(e);
-                    this.$message.error(e.error);
-                });
-        }
-        this.$http.post('/tag/all', { size: 10000 }, { body: 'json' }).then(res => {
-            this.tags = res.content;
-        });
-    },
-    data() {
-        return {
-            tags: [],
-            saving: false,
-            formData: {},
-            rules: {
-                detail: [
-                    {
-                        required: true,
-                        message: '请输入详情',
-                        trigger: 'blur'
-                    }
-                ],
-                application: [
-                    {
-                        required: true,
-                        message: '请输入用途',
-                        trigger: 'blur'
-                    }
-                ],
-                num: [
-                    {
-                        required: true,
-                        message: '请输入数量配置',
-                        trigger: 'blur'
-                    }
-                ],
-                audit: [
-                    {
-                        required: true,
-                        message: '请选择是否需要审核',
-                        trigger: 'blur'
-                    }
-                ],
-                rule: [
-                    { required: true, message: '请选择规则', trigger: 'blur' },
-                    {
-                        validator: (rule, value, callback) => {
-                            if (!this.formData.audit) {
-                                if (!this.formData.rule) {
-                                    callback(new Error('请填写规则'));
-                                } else if (!this.formData.rule.and) {
-                                    callback(new Error('请填写规则'));
-                                } else if (!this.formData.rule.and.length) {
-                                    callback(new Error('请填写规则'));
-                                } else {
-                                    for (let i = 0; i < this.formData.rule.and.length; i++) {
-                                        if (
-                                            !(this.formData.rule.and[i].detail && this.formData.rule.and[i].detail.tag)
-                                        ) {
-                                            callback(new Error('请选择'));
-                                            callback = null;
-                                            break;
-                                        }
-                                    }
-                                    if (callback) {
-                                        callback();
-                                    }
-                                }
-                            } else {
-                                callback();
-                            }
-                        }
-                    }
-                ]
-            }
-        };
-    },
-    computed: {
-        canEdit() {
-            return !!!this.$route.query.id;
-        }
-    },
-    methods: {
-        onSave() {
-            this.$refs.form.validate(valid => {
-                if (valid) {
-                    this.submit();
-                } else {
-                    return false;
-                }
-            });
-        },
-        submit() {
-            let data = { ...this.formData };
+	name: 'MetaDestroyActivityEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaDestroyActivity/get/' + this.$route.query.id)
+				.then(res => {
+					this.formData = res;
+				})
+				.catch(e => {
+					console.log(e);
+					this.$message.error(e.error);
+				});
+		}
+		this.$http.post('/tag/all', { size: 10000 }, { body: 'json' }).then(res => {
+			this.tags = res.content;
+		});
+	},
+	data() {
+		return {
+			tags: [],
+			saving: false,
+			formData: {},
+			rules: {
+				detail: [
+					{
+						required: true,
+						message: '请输入详情',
+						trigger: 'blur'
+					}
+				],
+				application: [
+					{
+						required: true,
+						message: '请输入用途',
+						trigger: 'blur'
+					}
+				],
+				num: [
+					{
+						required: true,
+						message: '请输入数量配置',
+						trigger: 'blur'
+					}
+				],
+				audit: [
+					{
+						required: true,
+						message: '请选择是否需要审核',
+						trigger: 'blur'
+					}
+				],
+				rule: [
+					{ required: true, message: '请选择规则', trigger: 'blur' },
+					{
+						validator: (rule, value, callback) => {
+							if (!this.formData.audit) {
+								if (!this.formData.rule) {
+									callback(new Error('请填写规则'));
+								} else if (!this.formData.rule.and) {
+									callback(new Error('请填写规则'));
+								} else if (!this.formData.rule.and.length) {
+									callback(new Error('请填写规则'));
+								} else {
+									for (let i = 0; i < this.formData.rule.and.length; i++) {
+										if (
+											!(this.formData.rule.and[i].detail && this.formData.rule.and[i].detail.tag)
+										) {
+											callback(new Error('请选择'));
+											callback = null;
+											break;
+										}
+									}
+									if (callback) {
+										callback();
+									}
+								}
+							} else {
+								callback();
+							}
+						}
+					}
+				]
+			}
+		};
+	},
+	computed: {
+		canEdit() {
+			return !!!this.$route.query.id;
+		}
+	},
+	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('/metaDestroyActivity/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(`/metaDestroyActivity/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 || '删除失败');
-                    }
-                });
-        },
-        addRule() {
-            if (!(this.formData.rule && this.formData.rule.and)) {
-                this.$set(this.formData, 'rule', { and: [] });
-            }
-            this.formData.rule.and.push({ detail: { tag: null, num: 1 } });
-        },
-        delRule(i) {
-            this.formData.rule.and.splice(i, 1);
-        }
-    }
+			this.saving = true;
+			this.$http
+				.post('/metaDestroyActivity/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(`/metaDestroyActivity/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 || '删除失败');
+					}
+				});
+		},
+		addRule() {
+			if (!(this.formData.rule && this.formData.rule.and)) {
+				this.$set(this.formData, 'rule', { and: [] });
+			}
+			this.formData.rule.and.push({ detail: { tag: null, num: 1 } });
+		},
+		delRule(i) {
+			this.formData.rule.and.splice(i, 1);
+		}
+	}
 };
 </script>
 <style lang="less" scoped>
 .width1 {
-	width: 150px;
+    width: 150px;
 }
 
 .rule-item {
-	display: flex;
-	align-items: center;
-	margin-bottom: 10px;
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
 
-	.icon-del {
-		color: #f56c6c;
-		cursor: pointer;
-		font-size: 18px;
-	}
+    .icon-del {
+        color: #f56c6c;
+        cursor: pointer;
+        font-size: 18px;
+    }
 }
 </style>

+ 188 - 188
src/main/vue/src/views/MetaDestroyActivityList.vue

@@ -1,93 +1,93 @@
 <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="detail" label="详情"> </el-table-column>
-			<el-table-column prop="awardPic" label="奖励图片">
-				<template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.awardPic"
-						fit="cover"
-						:preview-src-list="[row.awardPic]"
-					>
-					</el-image>
-				</template>
-			</el-table-column>
-			<el-table-column prop="audit" label="审核" width="80" align="center">
+    <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="detail" label="详情"> </el-table-column>
+            <el-table-column prop="awardPic" label="奖励图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.awardPic"
+                        fit="cover"
+                        :preview-src-list="[row.awardPic]"
+                    >
+                    </el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="audit" label="审核" width="80" align="center">
+                <template v-slot="{ row }">
+                    <el-tag type="warning" v-if="row.audit"> 人工 </el-tag>
+                    <el-tag type="success" v-else> 自动 </el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column prop="collectionName" label="藏品名称"> </el-table-column>
+            <el-table-column prop="rule" label="藏品规则">
                 <template v-slot="{ row }">
-                    <el-tag type="warning" v-if="row.audit">人工</el-tag>
-                    <el-tag type="success" v-else>自动</el-tag>
+                    <template v-if="row.rule">
+                        <div v-for="item in row.rule.tags" :key="item.id">
+                            {{ item.name }}
+                        </div>
+                    </template>
                 </template>
             </el-table-column>
-			<el-table-column prop="collectionName" label="藏品名称"> </el-table-column>
-			<el-table-column prop="rule" label="藏品规则">
-				<template v-slot="{ row }">
-					<template v-if="row.rule">
-						<div v-for="item in row.rule.tags" :key="item.id">
-							{{ item.name }}
-						</div>
-					</template>
-				</template>
-			</el-table-column>
-			<el-table-column prop="num" label="藏品数量" width="80" align="center"> </el-table-column>
+            <el-table-column prop="num" label="藏品数量" width="80" align="center"> </el-table-column>
             <el-table-column prop="application" label="用途"> </el-table-column>
-			<el-table-column prop="publish" 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-table-column prop="publish" 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>
@@ -95,115 +95,115 @@
                     <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-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: 'MetaDestroyActivityList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaDestroyActivity/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: '/metaDestroyActivityEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaDestroyActivityEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaDestroyActivity/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaDestroyActivity/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaDestroyActivityList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaDestroyActivity/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: '/metaDestroyActivityEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaDestroyActivityEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaDestroyActivity/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaDestroyActivity/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 138 - 136
src/main/vue/src/views/MetaDestroyRecordList.vue

@@ -1,150 +1,152 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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="userId" align="center" label="userId"> </el-table-column>
-			<el-table-column prop="assetId" align="center" label="assetId"> </el-table-column>
-			<el-table-column prop="record" align="center" label="record"> </el-table-column>
-			<el-table-column prop="name" align="center" label="name" width="300"> </el-table-column>
-			<el-table-column prop="pic" align="center" label="pic">
+    <div class="list-view">
+        <page-title>
+            <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="userId" align="center" label="userId"> </el-table-column>
+            <el-table-column prop="assetId" align="center" label="assetId"> </el-table-column>
+            <el-table-column prop="record" align="center" label="record"> </el-table-column>
+            <el-table-column prop="name" align="center" label="name" width="300"> </el-table-column>
+            <el-table-column prop="pic" align="center" label="pic">
                 <template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.pic"
-						fit="cover"
-						:preview-src-list="[row.pic]"
-					>
-					</el-image>
-				</template> </el-table-column>
-			<el-table-column prop="type" align="center" label="type" :formatter="typeFormatter"> </el-table-column>
-            <el-table-column prop="source" align="center" label="source" :formatter="sourceFormatter"> </el-table-column>
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.pic"
+                        fit="cover"
+                        :preview-src-list="[row.pic]"
+                    >
+                    </el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="type" align="center" label="type" :formatter="typeFormatter"> </el-table-column>
+            <el-table-column prop="source" align="center" label="source" :formatter="sourceFormatter">
+            </el-table-column>
             <el-table-column prop="remark" align="center" label="remark" width="300"> </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>
+        </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaDestroyRecordList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/destroyRecord/all',
-			downloading: false,
-			typeOptions: [
-				{ label: 'OBTAIN', value: 'OBTAIN' },
-				{ label: 'CONSUME', value: 'CONSUME' }
-			],
+    name: 'MetaDestroyRecordList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/destroyRecord/all',
+            downloading: false,
+            typeOptions: [
+                { label: 'OBTAIN', value: 'OBTAIN' },
+                { label: 'CONSUME', value: 'CONSUME' }
+            ],
             sourceOptions: [
-				{ label: '元宇宙', value: 'META' },
-				{ label: '绿洲', value: 'RAEX' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		typeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
+                { label: '元宇宙', value: 'META' },
+                { label: '绿洲', value: 'RAEX' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        typeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
         sourceFormatter(row, column, cellValue, index) {
-			let selectedOption = this.sourceOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false, source: 'META' } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/destroyRecord/excel', {
-					responseType: 'blob',
-					params: { size: 10000, query: { del: false, source: 'META' } }
-				})
-				.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);
-				});
-		}
-	}
+            let selectedOption = this.sourceOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false, source: 'META' } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/destroyRecord/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false, source: 'META' } }
+                })
+                .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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 102 - 102
src/main/vue/src/views/MetaGameBoxPointsList.vue

@@ -1,112 +1,112 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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="userId" align="center" label="用户ID"> </el-table-column>
-			<el-table-column prop="score" align="center" label="当前最高积分"> </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>
+    <div class="list-view">
+        <page-title>
+            <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="userId" align="center" label="用户ID"> </el-table-column>
+            <el-table-column prop="score" align="center" label="当前最高积分"> </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaGameBoxPointsList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaGameBoxPoints/all',
-			downloading: false
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		beforeGetData() {
-			return { search: this.search, query: { del: false }, sort:'score,desc' };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaGameBoxPoints/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);
-				});
-		}
-	}
+    name: 'MetaGameBoxPointsList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaGameBoxPoints/all',
+            downloading: false
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeGetData() {
+            return { search: this.search, query: { del: false }, sort: 'score,desc' };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaGameBoxPoints/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 487 - 471
src/main/vue/src/views/MetaGameCopyEdit.vue

@@ -1,486 +1,502 @@
 <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="108px"
-					label-position="right"
-					size="small"
-					style="max-width: 500px"
-				>
-					<el-form-item prop="gameName" label="游戏">
-						<el-select v-model="formData.gameName" clearable filterable placeholder="请选择">
-							<el-option
-								v-for="item in gameNameOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<el-form-item prop="gameCopyType" label="副本">
-						<el-select v-model="formData.gameCopyType" clearable filterable placeholder="请选择">
-							<el-option
-								v-for="item in gameCopyTypeOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<el-form-item label="金币入场配置">
-						<el-checkbox v-model="gold" @change="goldChange"> </el-checkbox>
-					</el-form-item>
-					<el-form-item prop="goldNum" label="所需金币数量" v-if="gold">
-						<el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
-						</el-input-number>
-						<div class="tip">输入规则:正整数,最小为1</div>
-					</el-form-item>
-					<el-form-item label="NFT入场配置">
-						<el-checkbox v-model="nft" @change="nftChange"> </el-checkbox>
-					</el-form-item>
-					<el-form-item prop="audit" label="是否需要审核" v-if="nft">
-						<el-radio-group v-model="formData.audit">
-							<el-radio :label="true"> 人工审核 </el-radio>
-							<el-radio :label="false"> 自动匹配 </el-radio>
-						</el-radio-group>
-					</el-form-item>
-					<el-form-item prop="collectionName" label="藏品名称" v-if="nft && formData.audit === true">
-						<el-input v-model="formData.collectionName" :disabled="!canEdit" class="width"> </el-input>
-					</el-form-item>
-					<el-form-item prop="rule" label="匹配规则设置" v-if="nft && formData.audit === false">
-						<template v-if="formData.rule && formData.rule.and">
-							<div v-for="(item, i) in formData.rule.and" class="rule-item">
-								<el-select v-model="item.detail.tag" value-key="id" size="mini">
-									<el-option v-for="item in tags" :key="item.id" :value="item" :label="item.name">
-									</el-option>
-								</el-select>
-								<span style="padding: 0 10px; color: #606266; font-weight: bold"> ×&nbsp;1 </span>
-								<i @click="delRule(i)" class="el-icon-delete icon-del"> </i>
-							</div>
-						</template>
-						<el-button size="mini" @click="addRule"> 添加 </el-button>
-					</el-form-item>
-					<el-form-item prop="num" label="所需nft数量" v-if="nft">
-						<el-input-number
-							type="number"
-							v-model="formData.num"
-							:disabled="!canEdit"
-							:step="1"
-							:min="0"
-							class="width1"
-						>
-						</el-input-number>
-						<div class="tip">0表示不限</div>
-					</el-form-item>
-					<el-form-item prop="detail" label="规则详情" style="width: calc(100vw - 450px)">
-						<el-input
-							v-model="formData.detail"
-							type="textarea"
-							:autosize="{ minRows: 3, maxRows: 20 }"
-							placeholder="请输入规则详情"
-						>
-						</el-input>
-					</el-form-item>
-					<el-form-item label="僵尸配置" prop="metaZombieIds">
-						<el-select v-model="formData.metaZombieIds" multiple placeholder="请选择" style="width: 100%">
-							<el-option v-for="item in metaZombie" :key="item.id" :label="item.name" :value="item.id">
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<el-form-item prop="metaGameAwards" label="奖励配置" style="width: calc(100vw - 450px)" size="mini">
-						<el-table :data="formData.metaGameAwards">
-							<el-table-column prop="name" label="奖励名称">
-								<template v-slot="{ row }">
-									<el-input v-model="row.name" style="width: 250px" placeholder="请输入奖励名称">
-									</el-input>
-								</template>
-							</el-table-column>
-							<el-table-column prop="awardType" label="奖励类型">
-								<template v-slot="{ row }">
-									<el-select
-										v-model="row.awardType"
-										clearable
-										filterable
-										placeholder="请选择"
-										@change="changeAwardType(row)"
-									>
-										<el-option
-											v-for="item in entryModeTypeOptions"
-											:key="item.value"
-											:label="item.label"
-											:value="item.value"
-										>
-										</el-option>
-									</el-select>
-								</template>
-							</el-table-column>
-							<el-table-column prop="config" label="配置值(金币-数量/NFT-NFT图片)">
-								<template v-slot="{ row }">
-									<template v-if="row && row.awardType === 'GOLD'">
-										<el-input-number v-model="row.config" :step="1" :min="1"> </el-input-number>
-										<div class="tip">输入规则:正整数,最小为1</div>
-									</template>
-									<template v-if="row && row.awardType === 'NFT'">
-										<single-upload v-model="row.config"> </single-upload>
-									</template>
-								</template>
-							</el-table-column>
-							<el-table-column prop="probability" label="概率(%)">
-								<template v-slot="{ row }">
-									<el-input-number v-model="row.probability" :step="1" :min="1" :max="100">
-									</el-input-number>
-									<div class="tip">输入规则:正整数,最小为1,最大为100</div>
-								</template>
-							</el-table-column>
-							<el-table-column width="80" align="center">
-								<template v-slot="{ row, $index }">
-									<el-button type="danger" plain size="mini" @click="delAward($index)">
-										删除
-									</el-button>
-								</template>
-							</el-table-column>
-						</el-table>
-					</el-form-item>
-					<el-form-item>
-						<el-button size="mini" @click="addAward"> 添加配置 </el-button>
-					</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>
+    <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="108px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px"
+                >
+                    <el-form-item prop="gameName" label="游戏">
+                        <el-select
+                            v-model="formData.gameName"
+                            clearable
+                            filterable
+                            placeholder="请选择"
+                            @change="changeGameName()"
+                        >
+                            <el-option
+                                v-for="item in gameNameOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item prop="gameCopyType" label="副本">
+                        <el-select v-model="formData.gameCopyType" clearable filterable placeholder="请选择">
+                            <el-option
+                                v-for="item in gameCopyTypeOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="金币入场配置">
+                        <el-checkbox v-model="gold" @change="goldChange"> </el-checkbox>
+                    </el-form-item>
+                    <el-form-item prop="goldNum" label="所需金币数量" v-if="gold">
+                        <el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
+                        </el-input-number>
+                        <div class="tip">输入规则:正整数,最小为1</div>
+                    </el-form-item>
+                    <el-form-item label="NFT入场配置">
+                        <el-checkbox v-model="nft" @change="nftChange"> </el-checkbox>
+                    </el-form-item>
+                    <el-form-item prop="audit" label="是否需要审核" v-if="nft">
+                        <el-radio-group v-model="formData.audit">
+                            <el-radio :label="true"> 人工审核 </el-radio>
+                            <el-radio :label="false"> 自动匹配 </el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+                    <el-form-item prop="collectionName" label="藏品名称" v-if="nft && formData.audit === true">
+                        <el-input v-model="formData.collectionName" :disabled="!canEdit" class="width"> </el-input>
+                    </el-form-item>
+                    <el-form-item prop="rule" label="匹配规则设置" v-if="nft && formData.audit === false">
+                        <template v-if="formData.rule && formData.rule.and">
+                            <div v-for="(item, i) in formData.rule.and" class="rule-item">
+                                <el-select v-model="item.detail.tag" value-key="id" size="mini">
+                                    <el-option v-for="item in tags" :key="item.id" :value="item" :label="item.name">
+                                    </el-option>
+                                </el-select>
+                                <span style="padding: 0 10px; color: #606266; font-weight: bold"> ×&nbsp;1 </span>
+                                <i @click="delRule(i)" class="el-icon-delete icon-del"> </i>
+                            </div>
+                        </template>
+                        <el-button size="mini" @click="addRule"> 添加 </el-button>
+                    </el-form-item>
+                    <el-form-item prop="num" label="所需nft数量" v-if="nft">
+                        <el-input-number
+                            type="number"
+                            v-model="formData.num"
+                            :disabled="!canEdit"
+                            :step="1"
+                            :min="0"
+                            class="width1"
+                        >
+                        </el-input-number>
+                        <div class="tip">0表示不限</div>
+                    </el-form-item>
+                    <el-form-item prop="detail" label="规则详情" style="width: calc(100vw - 450px)">
+                        <el-input
+                            v-model="formData.detail"
+                            type="textarea"
+                            :autosize="{ minRows: 3, maxRows: 20 }"
+                            placeholder="请输入规则详情"
+                        >
+                        </el-input>
+                    </el-form-item>
+                    <el-form-item
+                        label="僵尸配置"
+                        prop="metaZombieIds"
+                        v-if="formData.gameName && formData.gameName == 'ZOMBIE'"
+                    >
+                        <el-select v-model="formData.metaZombieIds" multiple placeholder="请选择" style="width: 100%">
+                            <el-option v-for="item in metaZombie" :key="item.id" :label="item.name" :value="item.id">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item prop="metaGameAwards" label="奖励配置" style="width: calc(100vw - 450px)" size="mini">
+                        <el-table :data="formData.metaGameAwards">
+                            <el-table-column prop="name" label="奖励名称">
+                                <template v-slot="{ row }">
+                                    <el-input v-model="row.name" style="width: 250px" placeholder="请输入奖励名称">
+                                    </el-input>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="awardType" label="奖励类型">
+                                <template v-slot="{ row }">
+                                    <el-select
+                                        v-model="row.awardType"
+                                        clearable
+                                        filterable
+                                        placeholder="请选择"
+                                        @change="changeAwardType(row)"
+                                    >
+                                        <el-option
+                                            v-for="item in entryModeTypeOptions"
+                                            :key="item.value"
+                                            :label="item.label"
+                                            :value="item.value"
+                                        >
+                                        </el-option>
+                                    </el-select>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="config" label="配置值(金币-数量/NFT-NFT图片)">
+                                <template v-slot="{ row }">
+                                    <template v-if="row && row.awardType === 'GOLD'">
+                                        <el-input-number v-model="row.config" :step="1" :min="1"> </el-input-number>
+                                        <div class="tip">输入规则:正整数,最小为1</div>
+                                    </template>
+                                    <template v-if="row && row.awardType === 'NFT'">
+                                        <single-upload v-model="row.config"> </single-upload>
+                                    </template>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="probability" label="概率(%)">
+                                <template v-slot="{ row }">
+                                    <el-input-number v-model="row.probability" :step="1" :min="1" :max="100">
+                                    </el-input-number>
+                                    <div class="tip">输入规则:正整数,最小为1,最大为100</div>
+                                </template>
+                            </el-table-column>
+                            <el-table-column width="80" align="center">
+                                <template v-slot="{ row, $index }">
+                                    <el-button type="danger" plain size="mini" @click="delAward($index)">
+                                        删除
+                                    </el-button>
+                                </template>
+                            </el-table-column>
+                        </el-table>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button size="mini" @click="addAward"> 添加配置 </el-button>
+                    </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: 'MetaGameCopyEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaGameCopy/get/' + this.$route.query.id)
-				.then(res => {
-					res.metaGameAwards = res.metaGameAwards || [];
-					this.formData = res;
-					if (res.entryModeType === 'GOLD') {
-						this.gold = true;
-						this.nft = false;
-					} else if (res.entryModeType === 'NFT') {
-						this.gold = false;
-						this.nft = true;
-					} else if (res.entryModeType === 'GOLD_OR_NFT') {
-						this.gold = true;
-						this.nft = true;
-					}
-				})
-				.catch(e => {
-					console.log(e);
-					this.$message.error(e.error);
-				});
-		}
-		this.$http.post('/tag/all', { size: 10000 }, { body: 'json' }).then(res => {
-			this.tags = res.content;
-		});
-		this.$http.get('/metaZombie/findAll').then(res => {
-			this.metaZombie = res;
-		});
-	},
-	data() {
-		return {
-			nft: false,
-			gold: false,
-			reg: /^[1-9]\d*$/,
-			awardType: [],
-			metaZombie: [],
-			tags: [],
-			saving: false,
-			formData: {
-				metaGameAwards: []
-			},
-			rules: {
-				detail: [
-					{
-						required: true,
-						message: '请输入规则详情',
-						trigger: 'blur'
-					}
-				],
-				gameName: [
-					{
-						required: true,
-						message: '请选择游戏',
-						trigger: 'blur'
-					}
-				],
-				gameCopyType: [
-					{
-						required: true,
-						message: '请选择副本',
-						trigger: 'blur'
-					}
-				],
-				goldNum: [
-					{
-						required: true,
-						message: '请输入所需金币数量',
-						trigger: 'blur'
-					},
-					{
-						validator: (rule, value, callback) => {
-							if (!this.reg.test(value)) {
-								callback(new Error('所需金币数量必须为大于1的整数'));
-								return;
-							} else {
-								callback();
-							}
-						}
-					}
-				],
-				rule: [
-					{ required: true, message: '请选择规则', trigger: 'blur' },
-					{
-						validator: (rule, value, callback) => {
-							if (!this.formData.audit) {
-								if (!this.formData.rule) {
-									callback(new Error('请填写规则'));
-								} else if (!this.formData.rule.and) {
-									callback(new Error('请填写规则'));
-								} else if (!this.formData.rule.and.length) {
-									callback(new Error('请填写规则'));
-								} else {
-									for (let i = 0; i < this.formData.rule.and.length; i++) {
-										if (
-											!(this.formData.rule.and[i].detail && this.formData.rule.and[i].detail.tag)
-										) {
-											callback(new Error('请选择'));
-											callback = null;
-											break;
-										}
-									}
-									if (callback) {
-										callback();
-									}
-								}
-							} else {
-								callback();
-							}
-						}
-					}
-				],
-				metaGameAwards: [
-					{
-						validator: (rule, value, callback) => {
-							if (value) {
-								if (!(value instanceof Array)) {
-									callback(new Error('metaGameAwards must be array!'));
-									return;
-								} else {
-									for (let i = 0; i < value.length; i++) {
-										if (
-											value[i].name === '' ||
-											value[i].name === undefined ||
-											value[i].name === null
-										) {
-											callback(new Error('请填写奖励名称'));
-											return;
-										}
-										if (
-											value[i].awardType === '' ||
-											value[i].awardType === undefined ||
-											value[i].awardType === null
-										) {
-											callback(new Error('请选择奖励类型'));
-											return;
-										}
-										if (
-											value[i].config === '' ||
-											value[i].config === undefined ||
-											value[i].config === null
-										) {
-											callback(new Error('请填写奖励配置'));
-											return;
-										}
-										if (value[i].awardType === 'GOLD' && !this.reg.test(value[i].config)) {
-											callback(new Error('奖励金币数量必须为大于1的整数'));
-											return;
-										}
-										if (
-											value[i].probability === '' ||
-											value[i].probability === undefined ||
-											value[i].probability === null
-										) {
-											callback(new Error('请填写奖励概率'));
-											return;
-										}
-										if (!this.reg.test(value[i].probability)) {
-											callback(new Error('奖励概率必须为大于1的整数'));
-											return;
-										}
-									}
-								}
-							}
-							callback();
-						},
-						trigger: 'blur'
-					}
-				],
-				audit: [
-					{
-						required: true,
-						message: '请选择是否审核',
-						trigger: 'blur'
-					}
-				],
-				collectionName: [
-					{
-						required: true,
-						message: '请输入藏品名称',
-						trigger: 'blur'
-					}
-				],
-				num: [
-					{
-						required: true,
-						message: '请输入所需nft数量',
-						trigger: 'blur'
-					}
-				]
-			},
-			gameNameOptions: [{ label: '僵尸', value: 'ZOMBIE' },{ label: '钓鱼', value: 'FISHING' }],
-			gameCopyTypeOptions: [
-				{ label: '青铜', value: 'BRONZE' },
-				{ label: '白银', value: 'SILVER' },
-				{ label: '黄金', value: 'GOLD' }
-			],
-			entryModeTypeOptions: [
-				{ label: 'NFT', value: 'NFT' },
-				{ label: '金币', value: 'GOLD' }
-			]
-		};
-	},
-	computed: {
-		canEdit() {
-			return !!!this.$route.query.id;
-		}
-	},
-	methods: {
-		goldChange() {
-			this.$delete(this.formData, 'goldNum');
-		},
-		nftChange() {
-			this.$delete(this.formData, 'audit');
-			this.$delete(this.formData, 'collectionName');
-			this.$delete(this.formData, 'rule');
-			this.$delete(this.formData, 'num');
-		},
-		changeAwardType(row) {
-			row.config = '';
-		},
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
-			if (this.gold && !this.nft) {
-				data.entryModeType = 'GOLD';
-			} else if (!this.gold && this.nft) {
-				data.entryModeType = 'NFT';
-			} else if (this.gold && this.nft) {
-				data.entryModeType = 'GOLD_OR_NFT';
-			} else if (!this.gold && !this.nft) {
-				this.$message.error('请最少配置一个入场方式');
+    name: 'MetaGameCopyEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaGameCopy/get/' + this.$route.query.id)
+                .then(res => {
+                    res.metaGameAwards = res.metaGameAwards || [];
+                    this.formData = res;
+                    if (res.entryModeType === 'GOLD') {
+                        this.gold = true;
+                        this.nft = false;
+                    } else if (res.entryModeType === 'NFT') {
+                        this.gold = false;
+                        this.nft = true;
+                    } else if (res.entryModeType === 'GOLD_OR_NFT') {
+                        this.gold = true;
+                        this.nft = true;
+                    }
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+        this.$http.post('/tag/all', { size: 10000 }, { body: 'json' }).then(res => {
+            this.tags = res.content;
+        });
+        this.$http.get('/metaZombie/findAll').then(res => {
+            this.metaZombie = res;
+        });
+    },
+    data() {
+        return {
+            nft: false,
+            gold: false,
+            reg: /^[1-9]\d*$/,
+            awardType: [],
+            metaZombie: [],
+            tags: [],
+            saving: false,
+            formData: {
+                metaGameAwards: []
+            },
+            rules: {
+                detail: [
+                    {
+                        required: true,
+                        message: '请输入规则详情',
+                        trigger: 'blur'
+                    }
+                ],
+                gameName: [
+                    {
+                        required: true,
+                        message: '请选择游戏',
+                        trigger: 'blur'
+                    }
+                ],
+                gameCopyType: [
+                    {
+                        required: true,
+                        message: '请选择副本',
+                        trigger: 'blur'
+                    }
+                ],
+                goldNum: [
+                    {
+                        required: true,
+                        message: '请输入所需金币数量',
+                        trigger: 'blur'
+                    },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!this.reg.test(value)) {
+                                callback(new Error('所需金币数量必须为大于1的整数'));
+                                return;
+                            } else {
+                                callback();
+                            }
+                        }
+                    }
+                ],
+                rule: [
+                    { required: true, message: '请选择规则', trigger: 'blur' },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!this.formData.audit) {
+                                if (!this.formData.rule) {
+                                    callback(new Error('请填写规则'));
+                                } else if (!this.formData.rule.and) {
+                                    callback(new Error('请填写规则'));
+                                } else if (!this.formData.rule.and.length) {
+                                    callback(new Error('请填写规则'));
+                                } else {
+                                    for (let i = 0; i < this.formData.rule.and.length; i++) {
+                                        if (
+                                            !(this.formData.rule.and[i].detail && this.formData.rule.and[i].detail.tag)
+                                        ) {
+                                            callback(new Error('请选择'));
+                                            callback = null;
+                                            break;
+                                        }
+                                    }
+                                    if (callback) {
+                                        callback();
+                                    }
+                                }
+                            } else {
+                                callback();
+                            }
+                        }
+                    }
+                ],
+                metaGameAwards: [
+                    {
+                        validator: (rule, value, callback) => {
+                            if (value) {
+                                if (!(value instanceof Array)) {
+                                    callback(new Error('metaGameAwards must be array!'));
+                                    return;
+                                } else {
+                                    for (let i = 0; i < value.length; i++) {
+                                        if (
+                                            value[i].name === '' ||
+                                            value[i].name === undefined ||
+                                            value[i].name === null
+                                        ) {
+                                            callback(new Error('请填写奖励名称'));
+                                            return;
+                                        }
+                                        if (
+                                            value[i].awardType === '' ||
+                                            value[i].awardType === undefined ||
+                                            value[i].awardType === null
+                                        ) {
+                                            callback(new Error('请选择奖励类型'));
+                                            return;
+                                        }
+                                        if (
+                                            value[i].config === '' ||
+                                            value[i].config === undefined ||
+                                            value[i].config === null
+                                        ) {
+                                            callback(new Error('请填写奖励配置'));
+                                            return;
+                                        }
+                                        if (value[i].awardType === 'GOLD' && !this.reg.test(value[i].config)) {
+                                            callback(new Error('奖励金币数量必须为大于1的整数'));
+                                            return;
+                                        }
+                                        if (
+                                            value[i].probability === '' ||
+                                            value[i].probability === undefined ||
+                                            value[i].probability === null
+                                        ) {
+                                            callback(new Error('请填写奖励概率'));
+                                            return;
+                                        }
+                                        if (!this.reg.test(value[i].probability)) {
+                                            callback(new Error('奖励概率必须为大于1的整数'));
+                                            return;
+                                        }
+                                    }
+                                }
+                            }
+                            callback();
+                        },
+                        trigger: 'blur'
+                    }
+                ],
+                audit: [
+                    {
+                        required: true,
+                        message: '请选择是否审核',
+                        trigger: 'blur'
+                    }
+                ],
+                collectionName: [
+                    {
+                        required: true,
+                        message: '请输入藏品名称',
+                        trigger: 'blur'
+                    }
+                ],
+                num: [
+                    {
+                        required: true,
+                        message: '请输入所需nft数量',
+                        trigger: 'blur'
+                    }
+                ]
+            },
+            gameNameOptions: [
+                { label: '僵尸', value: 'ZOMBIE' },
+                { label: '钓鱼', value: 'FISHING' }
+            ],
+            gameCopyTypeOptions: [
+                { label: '青铜', value: 'BRONZE' },
+                { label: '白银', value: 'SILVER' },
+                { label: '黄金', value: 'GOLD' }
+            ],
+            entryModeTypeOptions: [
+                { label: 'NFT', value: 'NFT' },
+                { label: '金币', value: 'GOLD' }
+            ]
+        };
+    },
+    computed: {
+        canEdit() {
+            return !!!this.$route.query.id;
+        }
+    },
+    methods: {
+        changeGameName() {
+            this.$delete(this.formData, 'metaZombieIds');
+        },
+        goldChange() {
+            this.$delete(this.formData, 'goldNum');
+        },
+        nftChange() {
+            this.$delete(this.formData, 'audit');
+            this.$delete(this.formData, 'collectionName');
+            this.$delete(this.formData, 'rule');
+            this.$delete(this.formData, 'num');
+        },
+        changeAwardType(row) {
+            row.config = '';
+        },
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
+            if (this.gold && !this.nft) {
+                data.entryModeType = 'GOLD';
+            } else if (!this.gold && this.nft) {
+                data.entryModeType = 'NFT';
+            } else if (this.gold && this.nft) {
+                data.entryModeType = 'GOLD_OR_NFT';
+            } else if (!this.gold && !this.nft) {
+                this.$message.error('请最少配置一个入场方式');
                 return;
-			}
-			this.saving = true;
-			this.$http
-				.post('/metaGameCopy/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(`/metaGameCopy/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 || '删除失败');
-					}
-				});
-		},
-		addRule() {
-			if (!(this.formData.rule && this.formData.rule.and)) {
-				this.$set(this.formData, 'rule', { and: [] });
-			}
-			this.formData.rule.and.push({ detail: { tag: null, num: 1 } });
-		},
-		delRule(i) {
-			this.formData.rule.and.splice(i, 1);
-		},
-		addAward() {
-			this.formData.metaGameAwards.push({
-				awardType: '',
-				config: '',
-				probability: ''
-			});
-		},
-		delAward(i) {
-			this.formData.metaGameAwards.splice(i, 1);
-		}
-	}
+            }
+            this.saving = true;
+            this.$http
+                .post('/metaGameCopy/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(`/metaGameCopy/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 || '删除失败');
+                    }
+                });
+        },
+        addRule() {
+            if (!(this.formData.rule && this.formData.rule.and)) {
+                this.$set(this.formData, 'rule', { and: [] });
+            }
+            this.formData.rule.and.push({ detail: { tag: null, num: 1 } });
+        },
+        delRule(i) {
+            this.formData.rule.and.splice(i, 1);
+        },
+        addAward() {
+            this.formData.metaGameAwards.push({
+                awardType: '',
+                config: '',
+                probability: ''
+            });
+        },
+        delAward(i) {
+            this.formData.metaGameAwards.splice(i, 1);
+        }
+    }
 };
 </script>
 <style lang="less" scoped>
 .width1 {
-    width: 150px;
+	width: 150px;
 }
 
 .rule-item {
-    display: flex;
-    align-items: center;
-    margin-bottom: 10px;
+	display: flex;
+	align-items: center;
+	margin-bottom: 10px;
 
-    .icon-del {
-        color: #f56c6c;
-        cursor: pointer;
-        font-size: 18px;
-    }
+	.icon-del {
+		color: #f56c6c;
+		cursor: pointer;
+		font-size: 18px;
+	}
 }
 </style>

+ 221 - 219
src/main/vue/src/views/MetaGameCopyList.vue

@@ -1,231 +1,233 @@
 <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" align="center" label="ID" width="100"> </el-table-column>
-			<el-table-column prop="gameName" align="center" label="名称" :formatter="gameNameFormatter"> </el-table-column>
-			<el-table-column prop="gameCopyType" align="center" label="副本" :formatter="gameCopyTypeFormatter"> </el-table-column>
-			<el-table-column prop="entryModeType" align="center" label="入场方式" :formatter="entryModeTypeFormatter">
-			</el-table-column>
-			<el-table-column prop="goldNum" align="center" label="所需金币数量"> </el-table-column>
-			<el-table-column prop="rule" label="藏品规则">
-				<template v-slot="{ row }">
-					<template v-if="row.rule">
-						<div v-for="item in row.rule.tags" :key="item.id">
-							{{ item.name }}
-						</div>
-					</template>
-				</template>
-			</el-table-column>
-			<el-table-column prop="audit" label="审核" width="80" align="center">
-				<template v-slot="{ row }">
-					<template v-if="row.entryModeType === 'NFT'">
-						<el-tag type="warning" v-if="row.audit"> 人工 </el-tag>
-						<el-tag type="success" v-else> 自动 </el-tag>
-					</template>
-				</template>
-			</el-table-column>
-			<el-table-column prop="collectionName" align="center" label="藏品名称"> </el-table-column>
-			<el-table-column prop="num" align="center" label="所需nft数量"> </el-table-column>
+    <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="gameName" align="center" label="名称" :formatter="gameNameFormatter">
+            </el-table-column>
+            <el-table-column prop="gameCopyType" align="center" label="副本" :formatter="gameCopyTypeFormatter">
+            </el-table-column>
+            <el-table-column prop="entryModeType" align="center" label="入场方式" :formatter="entryModeTypeFormatter">
+            </el-table-column>
+            <el-table-column prop="goldNum" align="center" label="所需金币数量"> </el-table-column>
+            <el-table-column prop="rule" label="藏品规则">
+                <template v-slot="{ row }">
+                    <template v-if="row.rule">
+                        <div v-for="item in row.rule.tags" :key="item.id">
+                            {{ item.name }}
+                        </div>
+                    </template>
+                </template>
+            </el-table-column>
+            <el-table-column prop="audit" label="审核" width="80" align="center">
+                <template v-slot="{ row }">
+                    <template v-if="row.entryModeType === 'NFT'">
+                        <el-tag type="warning" v-if="row.audit"> 人工 </el-tag>
+                        <el-tag type="success" v-else> 自动 </el-tag>
+                    </template>
+                </template>
+            </el-table-column>
+            <el-table-column prop="collectionName" align="center" label="藏品名称"> </el-table-column>
+            <el-table-column prop="num" align="center" label="所需nft数量"> </el-table-column>
             <el-table-column prop="detail" align="center" 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="350">
-				<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">
-			<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 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="350">
+                <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">
+            <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: 'MetaGameCopyList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaGameCopy/all',
-			downloading: false,
-			gameNameOptions: [
-				{ label: '僵尸游戏', value: 'ZOMBIE' },
-				{ label: '钓鱼游戏', value: 'FISHING' }
-			],
-			gameCopyTypeOptions: [
-				{ label: '青铜', value: 'BRONZE' },
-				{ label: '白银', value: 'SILVER' },
-				{ label: '黄金', value: 'GOLD' }
-			],
-			entryModeTypeOptions: [
-				{ label: 'NFT', value: 'NFT' },
-				{ label: '金币', value: 'GOLD' },
-				{ label: '金币或NFT', value: 'GOLD_OR_NFT' },
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		gameNameFormatter(row, column, cellValue, index) {
-			let selectedOption = this.gameNameOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		gameCopyTypeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.gameCopyTypeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		entryModeTypeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.entryModeTypeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaGameCopyEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaGameCopyEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaGameCopy/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaGameCopy/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaGameCopyList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaGameCopy/all',
+            downloading: false,
+            gameNameOptions: [
+                { label: '僵尸游戏', value: 'ZOMBIE' },
+                { label: '钓鱼游戏', value: 'FISHING' }
+            ],
+            gameCopyTypeOptions: [
+                { label: '青铜', value: 'BRONZE' },
+                { label: '白银', value: 'SILVER' },
+                { label: '黄金', value: 'GOLD' }
+            ],
+            entryModeTypeOptions: [
+                { label: 'NFT', value: 'NFT' },
+                { label: '金币', value: 'GOLD' },
+                { label: '金币或NFT', value: 'GOLD_OR_NFT' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        gameNameFormatter(row, column, cellValue, index) {
+            let selectedOption = this.gameNameOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        gameCopyTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.gameCopyTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        entryModeTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.entryModeTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaGameCopyEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaGameCopyEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaGameCopy/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaGameCopy/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 188 - 188
src/main/vue/src/views/MetaGameProcessList.vue

@@ -1,200 +1,200 @@
 <template>
-    <div class="list-view">
-        <page-title>
-            <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="createdAt" align="center" label="进度更新时间" width="200"></el-table-column>
-            <el-table-column prop="userId" align="center" label="玩家id"> </el-table-column>
+	<div class="list-view">
+		<page-title>
+			<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="createdAt" align="center" label="进度更新时间" width="200"> </el-table-column>
+			<el-table-column prop="userId" align="center" label="玩家id"> </el-table-column>
 			<el-table-column prop="phone" align="center" label="手机号" width="200"> </el-table-column>
-            <el-table-column prop="metaGameCopyId" align="center" label="游戏副本id"> </el-table-column>
-            <el-table-column prop="playerPos" align="center" label="玩家坐标" width="300">
-                <template slot-scope="{ row }">
-                    {{ 'x=' + row.playerPos.x + ' , ' + 'y=' + row.playerPos.y + ' , ' + 'z=' + row.playerPos.z }}
-                </template>
-            </el-table-column>
-            <el-table-column prop="point" align="center" label="当前积分"> </el-table-column>
-            <el-table-column prop="bulletCount" align="center" label="剩余子弹数"> </el-table-column>
-            <el-table-column prop="timeLeft" align="center" label="剩余时间(秒)"> </el-table-column>
-            <el-table-column prop="remainingHP" align="center" label="玩家剩余血量"> </el-table-column>
-            <el-table-column prop="hurt" align="center" label="是否收到伤害">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.hurt ? '' : 'info'"> {{ row.hurt }} </el-tag>
-                </template>
-            </el-table-column>
-            <el-table-column prop="disconnected" align="center" label="是否断线">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.disconnected ? '' : 'info'"> {{ row.disconnected }} </el-tag>
-                </template>
-            </el-table-column>
+			<el-table-column prop="metaGameCopyId" align="center" label="游戏副本id"> </el-table-column>
+			<el-table-column prop="playerPos" align="center" label="玩家坐标" width="300">
+				<template slot-scope="{ row }">
+					{{ 'x=' + row.playerPos.x + ' , ' + 'y=' + row.playerPos.y + ' , ' + 'z=' + row.playerPos.z }}
+				</template>
+			</el-table-column>
+			<el-table-column prop="point" align="center" label="当前积分"> </el-table-column>
+			<el-table-column prop="bulletCount" align="center" label="剩余子弹数"> </el-table-column>
+			<el-table-column prop="timeLeft" align="center" label="剩余时间(秒)"> </el-table-column>
+			<el-table-column prop="remainingHP" align="center" label="玩家剩余血量"> </el-table-column>
+			<el-table-column prop="hurt" align="center" label="是否收到伤害">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.hurt ? '' : 'info'"> {{ row.hurt }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="disconnected" align="center" label="是否断线">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.disconnected ? '' : 'info'"> {{ row.disconnected }} </el-tag>
+				</template>
+			</el-table-column>
 			<el-table-column prop="forceQuit" align="center" label="是否强制退出">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.forceQuit ? '' : 'info'"> {{ row.forceQuit }} </el-tag>
-                </template>
-            </el-table-column>
-            <el-table-column prop="completed" align="center" label="是否完成">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.completed ? '' : 'info'"> {{ row.completed }} </el-tag>
-                </template>
-            </el-table-column>
-            <el-table-column prop="metaGameAward" align="center" label="获得奖励">
-                <template slot-scope="{ row }">
-                    <template v-if="row.metaGameAward && row.metaGameAward.awardType === 'NFT'">
-                        <el-image
-                            style="width: 30px; height: 30px"
-                            :src="row.metaGameAward.config"
-                            fit="cover"
-                            :preview-src-list="[row.metaGameAward.config]"
-                        >
-                        </el-image>
-                    </template>
-                    <template v-if="row.metaGameAward && row.metaGameAward.awardType === 'GOLD'">
-                        {{ '金币:' + row.metaGameAward.config }}
-                    </template>
-                </template>
-            </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" width="150">
-                <template slot-scope="{ row }">
-                    <el-button @click="zombie(row)" type="primary" size="mini" plain> 查看僵尸信息 </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 :visible.sync="showZombieDialog" title="僵尸信息" width="1000px">
-            <el-table :data="zombieList" height="calc(100vh - 500px)">
-                <el-table-column prop="id" align="center" label="id" width="100"> </el-table-column>
-                <el-table-column prop="metaZombieId" align="center" label="僵尸配置id"> </el-table-column>
-                <el-table-column prop="createIndex" align="center" label="生成点id"> </el-table-column>
-                <el-table-column prop="type" align="center" label="类型" :formatter="typeFormatter"> </el-table-column>
-                <el-table-column prop="hp" align="center" label="剩余血量"> </el-table-column>
-                <el-table-column prop="killed" align="center" label="是否击杀">
-                    <template slot-scope="{ row }">
-                        <el-tag :type="row.killed ? '' : 'info'"> {{ row.killed }} </el-tag>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="pos" align="center" label="坐标" width="350">
-                    <template slot-scope="{ row }">
-                        {{ 'x=' + row.pos.x + ' , ' + 'y=' + row.pos.y + ' , ' + 'z=' + row.pos.z }}
-                    </template>
-                </el-table-column>
-            </el-table>
-        </el-dialog>
-    </div>
+				<template slot-scope="{ row }">
+					<el-tag :type="row.forceQuit ? '' : 'info'"> {{ row.forceQuit }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="completed" align="center" label="是否完成">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.completed ? '' : 'info'"> {{ row.completed }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="metaGameAward" align="center" label="获得奖励">
+				<template slot-scope="{ row }">
+					<template v-if="row.metaGameAward && row.metaGameAward.awardType === 'NFT'">
+						<el-image
+							style="width: 30px; height: 30px"
+							:src="row.metaGameAward.config"
+							fit="cover"
+							:preview-src-list="[row.metaGameAward.config]"
+						>
+						</el-image>
+					</template>
+					<template v-if="row.metaGameAward && row.metaGameAward.awardType === 'GOLD'">
+						{{ '金币:' + row.metaGameAward.config }}
+					</template>
+				</template>
+			</el-table-column>
+			<el-table-column label="操作" align="center" fixed="right" width="150">
+				<template slot-scope="{ row }">
+					<el-button @click="zombie(row)" type="primary" size="mini" plain> 查看僵尸信息 </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 :visible.sync="showZombieDialog" title="僵尸信息" width="1000px">
+			<el-table :data="zombieList" height="calc(100vh - 500px)">
+				<el-table-column prop="id" align="center" label="id" width="100"> </el-table-column>
+				<el-table-column prop="metaZombieId" align="center" label="僵尸配置id"> </el-table-column>
+				<el-table-column prop="createIndex" align="center" label="生成点id"> </el-table-column>
+				<el-table-column prop="type" align="center" label="类型" :formatter="typeFormatter"> </el-table-column>
+				<el-table-column prop="hp" align="center" label="剩余血量"> </el-table-column>
+				<el-table-column prop="killed" align="center" label="是否击杀">
+					<template slot-scope="{ row }">
+						<el-tag :type="row.killed ? '' : 'info'"> {{ row.killed }} </el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="pos" align="center" label="坐标" width="350">
+					<template slot-scope="{ row }">
+						{{ 'x=' + row.pos.x + ' , ' + 'y=' + row.pos.y + ' , ' + 'z=' + row.pos.z }}
+					</template>
+				</el-table-column>
+			</el-table>
+		</el-dialog>
+	</div>
 </template>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-    name: 'MetaGameProcessList',
-    mixins: [pageableTable],
-    data() {
-        return {
-            typeOptions: [
-                { label: '普通僵尸', value: 'COMMON' },
-                { label: '特殊僵尸', value: 'SPECIAL' }
-            ],
-            zombieList: [],
-            showZombieDialog: false,
-            multipleMode: false,
-            search: '',
-            url: '/metaGameProcess/all',
-            downloading: false
-        };
-    },
-    computed: {
-        selection() {
-            return this.$refs.table.selection.map(i => i.id);
-        }
-    },
-    methods: {
-        typeFormatter(row, column, cellValue, index) {
-            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
-            if (selectedOption) {
-                return selectedOption.label;
-            }
-            return '';
-        },
-        beforeGetData() {
-            return { search: this.search, query: { del: false } };
-        },
-        toggleMultipleMode(multipleMode) {
-            this.multipleMode = multipleMode;
-            if (!multipleMode) {
-                this.$refs.table.clearSelection();
-            }
-        },
-        zombie(row) {
-            this.zombieList = row.metaZombieDTOS;
-            this.showZombieDialog = true;
-        },
-        download() {
-            this.downloading = true;
-            this.$axios
-                .get('/metaGameProcess/excel', {
-                    responseType: 'blob',
-                    params: { size: 10000, query: { del: false } }
-                })
-                .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);
-                });
-        }
-    }
+	name: 'MetaGameProcessList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			typeOptions: [
+				{ label: '普通僵尸', value: 'COMMON' },
+				{ label: '特殊僵尸', value: 'SPECIAL' }
+			],
+			zombieList: [],
+			showZombieDialog: false,
+			multipleMode: false,
+			search: '',
+			url: '/metaGameProcess/all',
+			downloading: false
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		typeFormatter(row, column, cellValue, index) {
+			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+			if (selectedOption) {
+				return selectedOption.label;
+			}
+			return '';
+		},
+		beforeGetData() {
+			return { search: this.search, query: { del: false } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		zombie(row) {
+			this.zombieList = row.metaZombieDTOS;
+			this.showZombieDialog = true;
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaGameProcess/excel', {
+					responseType: 'blob',
+					params: { size: 10000, query: { del: false } }
+				})
+				.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);
+				});
+		}
+	}
 };
 </script>
 <style lang="less" scoped>

+ 144 - 144
src/main/vue/src/views/MetaGameStageAwardEdit.vue

@@ -1,152 +1,152 @@
 <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="gameName" label="游戏">
-						<el-select v-model="formData.gameName" clearable filterable placeholder="请选择">
-							<el-option
-								v-for="item in gameNameOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<el-form-item prop="point" label="积分">
-						<el-input-number type="number" v-model="formData.point" :step="1" :min="1"> </el-input-number>
-						<div class="tip">输入规则:正整数,最小为1</div>
-					</el-form-item>
-					<el-form-item prop="awardPic" label="奖励图片">
-						<single-upload v-model="formData.awardPic"> </single-upload>
-					</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="gameName" label="游戏">
+                        <el-select v-model="formData.gameName" clearable filterable placeholder="请选择">
+                            <el-option
+                                v-for="item in gameNameOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item prop="point" label="积分">
+                        <el-input-number type="number" v-model="formData.point" :step="1" :min="1"> </el-input-number>
+                        <div class="tip">输入规则:正整数,最小为1</div>
+                    </el-form-item>
+                    <el-form-item prop="awardPic" label="奖励图片">
+                        <single-upload v-model="formData.awardPic"> </single-upload>
+                    </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: 'MetaGameStageAwardEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaGameStageAward/get/' + this.$route.query.id)
-				.then(res => {
-					this.formData = res;
-				})
-				.catch(e => {
-					console.log(e);
-					this.$message.error(e.error);
-				});
-		}
-	},
-	data() {
-		return {
-			reg: /^[1-9]\d*$/,
-			saving: false,
-			formData: {},
-			rules: {
-				gameName: [
-					{
-						required: true,
-						message: '请选择游戏',
-						trigger: 'blur'
-					}
-				],
-				point: [
-					{
-						required: true,
-						message: '请输入积分',
-						trigger: 'blur'
-					},
-					{
-						validator: (rule, value, callback) => {
-							if (!this.reg.test(value)) {
-								callback(new Error('积分必须为大于1的整数'));
-								return;
-							} else {
-								callback();
-							}
-						}
-					}
-				],
-				awardPic: [
-					{
-						required: true,
-						message: '请输入奖励图片',
-						trigger: 'blur'
-					}
-				]
-			},
-			gameNameOptions: [{ label: '僵尸游戏', value: 'ZOMBIE' }]
-		};
-	},
-	methods: {
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+    name: 'MetaGameStageAwardEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaGameStageAward/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            reg: /^[1-9]\d*$/,
+            saving: false,
+            formData: {},
+            rules: {
+                gameName: [
+                    {
+                        required: true,
+                        message: '请选择游戏',
+                        trigger: 'blur'
+                    }
+                ],
+                point: [
+                    {
+                        required: true,
+                        message: '请输入积分',
+                        trigger: 'blur'
+                    },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!this.reg.test(value)) {
+                                callback(new Error('积分必须为大于1的整数'));
+                                return;
+                            } else {
+                                callback();
+                            }
+                        }
+                    }
+                ],
+                awardPic: [
+                    {
+                        required: true,
+                        message: '请输入奖励图片',
+                        trigger: 'blur'
+                    }
+                ]
+            },
+            gameNameOptions: [{ label: '僵尸游戏', value: 'ZOMBIE' }]
+        };
+    },
+    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('/metaGameStageAward/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(`/metaGameStageAward/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('/metaGameStageAward/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(`/metaGameStageAward/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>

+ 178 - 178
src/main/vue/src/views/MetaGameStageAwardList.vue

@@ -1,71 +1,71 @@
 <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="gameName" label="游戏" :formatter="gameNameFormatter"> </el-table-column>
-			<el-table-column prop="point" label="积分"> </el-table-column>
-			<el-table-column prop="awardPic" label="奖励图片">
-				<template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.awardPic"
-						fit="cover"
-						:preview-src-list="[row.awardPic]"
-					>
-					</el-image>
-				</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">
+    <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="gameName" label="游戏" :formatter="gameNameFormatter"> </el-table-column>
+            <el-table-column prop="point" label="积分"> </el-table-column>
+            <el-table-column prop="awardPic" label="奖励图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.awardPic"
+                        fit="cover"
+                        :preview-src-list="[row.awardPic]"
+                    >
+                    </el-image>
+                </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>
@@ -73,123 +73,123 @@
                     <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-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: 'MetaGameStageAwardList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaGameStageAward/all',
-			downloading: false,
-			gameNameOptions: [{ label: '僵尸游戏', value: 'ZOMBIE' }]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		gameNameFormatter(row, column, cellValue, index) {
-			let selectedOption = this.gameNameOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaGameStageAwardEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaGameStageAwardEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaGameStageAward/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaGameStageAward/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaGameStageAwardList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaGameStageAward/all',
+            downloading: false,
+            gameNameOptions: [{ label: '僵尸游戏', value: 'ZOMBIE' }]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        gameNameFormatter(row, column, cellValue, index) {
+            let selectedOption = this.gameNameOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaGameStageAwardEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaGameStageAwardEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaGameStageAward/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaGameStageAward/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 125 - 125
src/main/vue/src/views/MetaItemEdit.vue

@@ -1,133 +1,133 @@
 <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="type" label="物品类型">
-                        <el-select v-model="formData.type" clearable filterable placeholder="请选择">
-                            <el-option
-                                v-for="item in typeOptions"
-                                :key="item.value"
-                                :label="item.label"
-                                :value="item.value"
-                            >
-                            </el-option>
-                        </el-select>
-                    </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="name" label="物品名称">
+						<el-input v-model="formData.name"> </el-input>
+					</el-form-item>
+					<el-form-item prop="type" label="物品类型">
+						<el-select v-model="formData.type" clearable filterable placeholder="请选择">
+							<el-option
+								v-for="item in typeOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+					</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: 'MetaItemEdit',
-    created() {
-        if (this.$route.query.id) {
-            this.$http
-                .get('metaItem/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: {
-                name: [
-                    {
-                        required: true,
-                        message: '请输入物品名称',
-                        trigger: 'blur'
-                    }
-                ],
-                type: [
-                    {
-                        required: true,
-                        message: '请输入物品类型',
-                        trigger: 'blur'
-                    }
-                ]
-            },
-            typeOptions: [
-                { label: '元宇宙展厅', value: 'META_SHOW_ROOM' },
-                { label: '建筑', value: 'BUILDING' }
-            ]
-        };
-    },
-    methods: {
-        onSave() {
-            this.$refs.form.validate(valid => {
-                if (valid) {
-                    this.submit();
-                } else {
-                    return false;
-                }
-            });
-        },
-        submit() {
-            let data = { ...this.formData };
+	name: 'MetaItemEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaItem/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: {
+				name: [
+					{
+						required: true,
+						message: '请输入物品名称',
+						trigger: 'blur'
+					}
+				],
+				type: [
+					{
+						required: true,
+						message: '请输入物品类型',
+						trigger: 'blur'
+					}
+				]
+			},
+			typeOptions: [
+				{ label: '元宇宙展厅', value: 'META_SHOW_ROOM' },
+				{ label: '建筑', value: 'BUILDING' }
+			]
+		};
+	},
+	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('/metaItem/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(`/metaItem/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('/metaItem/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(`/metaItem/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>

+ 170 - 170
src/main/vue/src/views/MetaItemList.vue

@@ -1,60 +1,60 @@
 <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" align="center" label="ID" width="100"> </el-table-column>
-			<el-table-column prop="name" align="center" label="物品名称"> </el-table-column>
-			<el-table-column prop="type" align="center" label="物品类型" :formatter="typeFormatter"> </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">
+    <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="name" align="center" label="物品名称"> </el-table-column>
+            <el-table-column prop="type" align="center" label="物品类型" :formatter="typeFormatter"> </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>
@@ -62,126 +62,126 @@
                     <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-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: 'MetaItemList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaItem/all',
-			downloading: false,
-			typeOptions: [
-				{ label: '元宇宙展厅', value: 'META_SHOW_ROOM' },
-				{ label: '建筑', value: 'BUILDING' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		typeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaItemEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaItemEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaItem/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaItem/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaItemList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaItem/all',
+            downloading: false,
+            typeOptions: [
+                { label: '元宇宙展厅', value: 'META_SHOW_ROOM' },
+                { label: '建筑', value: 'BUILDING' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        typeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaItemEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaItemEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaItem/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaItem/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 120 - 120
src/main/vue/src/views/MetaMMOLoginInfoList.vue

@@ -1,130 +1,130 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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="nickname" label="昵称"> </el-table-column>
-			<el-table-column prop="userId" label="用户id"> </el-table-column>
-			<el-table-column prop="regionId" label="区域id"> </el-table-column>
-			<el-table-column prop="cityId" label="城市id"> </el-table-column>
-			<el-table-column prop="onLineTime" label="上线时间" width="150"> </el-table-column>
-			<el-table-column prop="offLineTime" label="离线时间" width="150"> </el-table-column>
-			<el-table-column prop="sessionId" label="sessionId"> </el-table-column>
-			<el-table-column prop="role" label="角色"> </el-table-column>
-			<el-table-column prop="axisX" label="axisX"> </el-table-column>
-			<el-table-column prop="axisY" label="axisY"> </el-table-column>
-			<el-table-column prop="axisZ" label="axisZ"> </el-table-column>
-			<el-table-column prop="eulerX" label="eulerX"> </el-table-column>
-			<el-table-column prop="eulerY" label="eulerY"> </el-table-column>
-			<el-table-column prop="eulerZ" label="eulerZ"> </el-table-column>
-			<el-table-column prop="top" label="top"> </el-table-column>
-			<el-table-column prop="hat" label="hat"> </el-table-column>
-			<el-table-column prop="down" label="down"> </el-table-column>
-			<el-table-column prop="shoes" label="shoes"> </el-table-column>
-			<el-table-column prop="anim" label="anim"> </el-table-column>
-			<el-table-column prop="emoji" label="emoji"> </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>
+    <div class="list-view">
+        <page-title>
+            <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="nickname" label="昵称"> </el-table-column>
+            <el-table-column prop="userId" label="用户id"> </el-table-column>
+            <el-table-column prop="regionId" label="区域id"> </el-table-column>
+            <el-table-column prop="cityId" label="城市id"> </el-table-column>
+            <el-table-column prop="onLineTime" label="上线时间" width="150"> </el-table-column>
+            <el-table-column prop="offLineTime" label="离线时间" width="150"> </el-table-column>
+            <el-table-column prop="sessionId" label="sessionId"> </el-table-column>
+            <el-table-column prop="role" label="角色"> </el-table-column>
+            <el-table-column prop="axisX" label="axisX"> </el-table-column>
+            <el-table-column prop="axisY" label="axisY"> </el-table-column>
+            <el-table-column prop="axisZ" label="axisZ"> </el-table-column>
+            <el-table-column prop="eulerX" label="eulerX"> </el-table-column>
+            <el-table-column prop="eulerY" label="eulerY"> </el-table-column>
+            <el-table-column prop="eulerZ" label="eulerZ"> </el-table-column>
+            <el-table-column prop="top" label="top"> </el-table-column>
+            <el-table-column prop="hat" label="hat"> </el-table-column>
+            <el-table-column prop="down" label="down"> </el-table-column>
+            <el-table-column prop="shoes" label="shoes"> </el-table-column>
+            <el-table-column prop="anim" label="anim"> </el-table-column>
+            <el-table-column prop="emoji" label="emoji"> </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaMMOLoginInfoList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaMMOLoginInfo/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();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaMMOLoginInfo/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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);
-				});
-		}
-	}
+    name: 'MetaMMOLoginInfoList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaMMOLoginInfo/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();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaMMOLoginInfo/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 181 - 177
src/main/vue/src/views/MetaPlayerRoleClassifyEdit.vue

@@ -1,184 +1,188 @@
 <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="120px"
-					label-position="right"
-					size="small"
-					style="max-width: 500px"
-				>
-					<el-form-item prop="classify" label="角色分类名称">
-						<el-input v-model="formData.classify"> </el-input>
-					</el-form-item>
-					<el-form-item
-						prop="metaPlayerRoleList"
-						label="角色列表"
-						style="width: calc(100vw - 450px)"
-						size="mini"
-					>
-						<el-table :data="formData.metaPlayerRoleList">
-							<el-table-column prop="id" label="角色id">
-								<template v-slot="{ row }">
-									<el-input v-model="row.id" style="width: 250px" placeholder="请输入角色id">
-									</el-input>
-								</template>
-							</el-table-column>
-							<el-table-column prop="name" label="角色名称">
-								<template v-slot="{ row }">
-									<el-input v-model="row.name" style="width: 250px" placeholder="请输入角色名称">
-									</el-input>
-								</template>
-							</el-table-column>
-							<el-table-column width="80" align="center">
-								<template v-slot="{ row, $index }">
-									<el-button type="danger" plain size="mini" @click="delRole($index)">
-										删除
-									</el-button>
-								</template>
-							</el-table-column>
-						</el-table>
-					</el-form-item>
-					<el-form-item>
-						<el-button size="mini" @click="addRole"> 添加配置 </el-button>
-						<div class="tip">请最少输入一个角色</div>
-					</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="120px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px"
+                >
+                    <el-form-item prop="classify" label="角色分类名称">
+                        <el-input v-model="formData.classify"> </el-input>
+                    </el-form-item>
+                    <el-form-item
+                        prop="metaPlayerRoleList"
+                        label="角色列表"
+                        style="width: calc(100vw - 450px)"
+                        size="mini"
+                    >
+                        <el-table :data="formData.metaPlayerRoleList">
+                            <el-table-column prop="id" label="角色id">
+                                <template v-slot="{ row }">
+                                    <el-input v-model="row.id" style="width: 250px" placeholder="请输入角色id">
+                                    </el-input>
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="name" label="角色名称">
+                                <template v-slot="{ row }">
+                                    <el-input v-model="row.name" style="width: 250px" placeholder="请输入角色名称">
+                                    </el-input>
+                                </template>
+                            </el-table-column>
+                            <el-table-column width="80" align="center">
+                                <template v-slot="{ row, $index }">
+                                    <el-button type="danger" plain size="mini" @click="delRole($index)">
+                                        删除
+                                    </el-button>
+                                </template>
+                            </el-table-column>
+                        </el-table>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button size="mini" @click="addRole"> 添加配置 </el-button>
+                        <div class="tip">请最少输入一个角色</div>
+                    </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: 'MetaPlayerRoleClassifyEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaPlayerRoleClassify/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: { metaPlayerRoleList: [{ id: '', name: '' }] },
-			rules: {
-				classify: [
-					{
-						required: true,
-						message: '请输入角色分类',
-						trigger: 'blur'
-					}
-				],
-				metaPlayerRoleList: [
-					{
-						validator: (rule, value, callback) => {
-							if (value) {
-								if (!(value instanceof Array)) {
-									callback(new Error('metaPlayerRoleList must be array!'));
-									return;
-								} else {
-									for (let i = 0; i < value.length; i++) {
-										if (value[i].id === '' || value[i].id === undefined || value[i].id === null) {
-											callback(new Error('请输入角色id'));
-											return;
-										}
-										if (
-											value[i].name === '' ||
-											value[i].name === undefined ||
-											value[i].name === null
-										) {
-											callback(new Error('请输入角色名称'));
-											return;
-										}
-									}
-								}
-							}
-							callback();
-						},
-						trigger: 'blur'
-					}
-				]
-			}
-		};
-	},
-	methods: {
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
-			if (data.metaPlayerRoleList.length == 0 || data.metaPlayerRoleList === null || data.metaPlayerRoleList === undefined) {
-				this.$message.error('请最少输入一个角色');
-			} else {
-				this.saving = true;
-				this.$http
-					.post('/metaPlayerRoleClassify/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(`/metaPlayerRoleClassify/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 || '删除失败');
-					}
-				});
-		},
-		addRole() {
-			this.formData.metaPlayerRoleList.push({
-				id: '',
-				name: ''
-			});
-		},
-		delRole(i) {
-			this.formData.metaPlayerRoleList.splice(i, 1);
-		}
-	}
+    name: 'MetaPlayerRoleClassifyEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaPlayerRoleClassify/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: { metaPlayerRoleList: [{ id: '', name: '' }] },
+            rules: {
+                classify: [
+                    {
+                        required: true,
+                        message: '请输入角色分类',
+                        trigger: 'blur'
+                    }
+                ],
+                metaPlayerRoleList: [
+                    {
+                        validator: (rule, value, callback) => {
+                            if (value) {
+                                if (!(value instanceof Array)) {
+                                    callback(new Error('metaPlayerRoleList must be array!'));
+                                    return;
+                                } else {
+                                    for (let i = 0; i < value.length; i++) {
+                                        if (value[i].id === '' || value[i].id === undefined || value[i].id === null) {
+                                            callback(new Error('请输入角色id'));
+                                            return;
+                                        }
+                                        if (
+                                            value[i].name === '' ||
+                                            value[i].name === undefined ||
+                                            value[i].name === null
+                                        ) {
+                                            callback(new Error('请输入角色名称'));
+                                            return;
+                                        }
+                                    }
+                                }
+                            }
+                            callback();
+                        },
+                        trigger: 'blur'
+                    }
+                ]
+            }
+        };
+    },
+    methods: {
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
+            if (
+                data.metaPlayerRoleList.length == 0 ||
+                data.metaPlayerRoleList === null ||
+                data.metaPlayerRoleList === undefined
+            ) {
+                this.$message.error('请最少输入一个角色');
+            } else {
+                this.saving = true;
+                this.$http
+                    .post('/metaPlayerRoleClassify/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(`/metaPlayerRoleClassify/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 || '删除失败');
+                    }
+                });
+        },
+        addRole() {
+            this.formData.metaPlayerRoleList.push({
+                id: '',
+                name: ''
+            });
+        },
+        delRole(i) {
+            this.formData.metaPlayerRoleList.splice(i, 1);
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 164 - 164
src/main/vue/src/views/MetaPlayerRoleClassifyList.vue

@@ -1,68 +1,68 @@
 <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="classify" label="角色分类"> </el-table-column>
+    <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="classify" label="角色分类"> </el-table-column>
             <el-table-column prop="metaPlayerRoleList" label="角色列表">
                 <template v-slot="{ row }">
-					<template v-if="row.metaPlayerRoleList">
-						<div v-for="item in row.metaPlayerRoleList" :key="item.id">
-							{{ item.name }}
-						</div>
-					</template>
-				</template>
+                    <template v-if="row.metaPlayerRoleList">
+                        <div v-for="item in row.metaPlayerRoleList" :key="item.id">
+                            {{ item.name }}
+                        </div>
+                    </template>
+                </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-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>
@@ -70,115 +70,115 @@
                     <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-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: 'MetaPlayerRoleClassifyList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaPlayerRoleClassify/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: '/metaPlayerRoleClassifyEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaPlayerRoleClassifyEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaPlayerRoleClassify/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(`/metaPlayerRoleClassify/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaPlayerRoleClassifyList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaPlayerRoleClassify/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: '/metaPlayerRoleClassifyEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaPlayerRoleClassifyEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaPlayerRoleClassify/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaPlayerRoleClassify/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 154 - 153
src/main/vue/src/views/MetaPlayerWearEdit.vue

@@ -1,64 +1,64 @@
 <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="userId" label="用户id">
-						<el-input-number type="number" v-model="formData.userId"> </el-input-number>
-					</el-form-item>
+    <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="userId" label="用户id">
+                        <el-input-number type="number" v-model="formData.userId"> </el-input-number>
+                    </el-form-item>
                     <el-form-item prop="model" label="模型">
-						<model-upload
-							:limit="1"
-							v-model="formData.model"
-							:customUrl="customUrl"
-							accept="application/zip"
-							format="json"
-							single
-						>
-						</model-upload>
-						<div class="tip">请将FBX文件与贴图打包成zip压缩包上传</div>
-					</el-form-item>
-					<el-form-item label="相机距离" v-if="formData.model">
-						<el-input-number v-model="scale" :min="0.1" :step="0.1"> </el-input-number>
-					</el-form-item>
-					<el-form-item label="Y轴偏移" v-if="formData.model">
-						<el-input-number v-model="yOffset"> </el-input-number>
-					</el-form-item>
-					<el-form-item prop="type" label="类型">
-						<el-select v-model="formData.type" clearable filterable placeholder="请选择">
-							<el-option
-								v-for="item in typeOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</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>
+                        <model-upload
+                            :limit="1"
+                            v-model="formData.model"
+                            :customUrl="customUrl"
+                            accept="application/zip"
+                            format="json"
+                            single
+                        >
+                        </model-upload>
+                        <div class="tip">请将FBX文件与贴图打包成zip压缩包上传</div>
+                    </el-form-item>
+                    <el-form-item label="相机距离" v-if="formData.model">
+                        <el-input-number v-model="scale" :min="0.1" :step="0.1"> </el-input-number>
+                    </el-form-item>
+                    <el-form-item label="Y轴偏移" v-if="formData.model">
+                        <el-input-number v-model="yOffset"> </el-input-number>
+                    </el-form-item>
+                    <el-form-item prop="type" label="类型">
+                        <el-select v-model="formData.type" clearable filterable placeholder="请选择">
+                            <el-option
+                                v-for="item in typeOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </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>
 import resolveUrl from 'resolve-url';
@@ -66,113 +66,114 @@ import ModelUpload from '../components/ModelUpload.vue';
 import SingleUpload from '../components/SingleUpload.vue';
 import TagSelect from '../components/TagSelect.vue';
 export default {
-	name: 'MetaPlayerWearEdit',
+    name: 'MetaPlayerWearEdit',
     components: { ModelUpload, SingleUpload, TagSelect },
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaPlayerWear/get/' + this.$route.query.id)
-				.then(res => {
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaPlayerWear/get/' + this.$route.query.id)
+                .then(res => {
                     if (res.model) {
                         let url = new URL(res.model.url);
                         this.scale = Number(url.searchParams.get('scale')) || 1;
                         this.yOffset = Number(url.searchParams.get('yOffset')) || 0;
                         res.model.url = url.origin + url.pathname;
                     }
-					this.formData = res;
-				})
-				.catch(e => {
-					console.log(e);
-					this.$message.error(e.error);
-				});
-		}
-	},
-	data() {
-		return {
-			saving: false,
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            saving: false,
             scale: 1,
-			yOffset: 0,
+            yOffset: 0,
             customUrl: resolveUrl(this.$baseUrl, 'upload/3dModel'),
-			formData: {},
-			rules: {
-				userId: [
-					{
-						required: true,
-						message: '请输入用户id',
-						trigger: 'blur'
-					}
-				],
-				model: [
-					{
-						required: true,
-						message: '请上传模型',
-						trigger: 'blur'
-					}
-				],
-				type: [
-					{
-						required: true,
-						message: '请输入类型',
-						trigger: 'blur'
-					}
-				]
-			},
-			typeOptions: [
-				{ label: '头饰', value: 'HEADDRESS' },
-				{ label: '衣服', value: 'CLOTHES' },
-				{ label: '裤子', value: 'TROUSERS' },
-				{ label: '鞋子', value: 'SHOES' },
-				{ label: '动作', value: 'ACTION' }
-			]
-		};
-	},
-	methods: {
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+            formData: {},
+            rules: {
+                userId: [
+                    {
+                        required: true,
+                        message: '请输入用户id',
+                        trigger: 'blur'
+                    }
+                ],
+                model: [
+                    {
+                        required: true,
+                        message: '请上传模型',
+                        trigger: 'blur'
+                    }
+                ],
+                type: [
+                    {
+                        required: true,
+                        message: '请输入类型',
+                        trigger: 'blur'
+                    }
+                ]
+            },
+            typeOptions: [
+                { label: '头饰', value: 'HEADDRESS' },
+                { label: '衣服', value: 'CLOTHES' },
+                { label: '裤子', value: 'TROUSERS' },
+                { label: '鞋子', value: 'SHOES' },
+                { label: '动作', value: 'ACTION' }
+            ]
+        };
+    },
+    methods: {
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
             if (data.model) {
                 data.model.url = data.model.url + '?scale=' + this.scale + '&yOffset=' + this.yOffset;
             }
-			this.saving = true;
-			this.$http
-				.post('/metaPlayerWear/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(`/metaPlayerWear/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('/metaPlayerWear/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(`/metaPlayerWear/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>

+ 175 - 174
src/main/vue/src/views/MetaPlayerWearList.vue

@@ -1,61 +1,61 @@
 <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="userId" label="用户id"> </el-table-column>
-			<el-table-column prop="model.name" label="模型"> </el-table-column>
-			<el-table-column prop="type" label="类型" :formatter="typeFormatter"> </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">
+    <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="userId" label="用户id"> </el-table-column>
+            <el-table-column prop="model.name" label="模型"> </el-table-column>
+            <el-table-column prop="type" label="类型" :formatter="typeFormatter"> </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>
@@ -63,130 +63,131 @@
                     <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-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: 'MetaPlayerWearList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaPlayerWear/all',
-			downloading: false,
-			typeOptions: [
-				{ label: '头饰', value: 'HEADDRESS' },
-				{ label: '衣服', value: 'CLOTHES' },
-				{ label: '裤子', value: 'TROUSERS' },
-				{ label: '鞋子', value: 'SHOES' },
-				{ label: '动作', value: 'ACTION' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		typeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaPlayerWearEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaPlayerWearEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaPlayerWear/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaPlayerWear/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaPlayerWearList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaPlayerWear/all',
+            downloading: false,
+            typeOptions: [
+                { label: '头饰', value: 'HEADDRESS' },
+                { label: '衣服', value: 'CLOTHES' },
+                { label: '裤子', value: 'TROUSERS' },
+                { label: '鞋子', value: 'SHOES' },
+                { label: '动作', value: 'ACTION' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        typeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaPlayerWearEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaPlayerWearEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaPlayerWear/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaPlayerWear/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>

+ 113 - 113
src/main/vue/src/views/MetaResourceVersionEdit.vue

@@ -1,120 +1,120 @@
 <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="108px"
-					label-position="right"
-					size="small"
-					style="max-width: 800px"
-				>
-					<el-form-item prop="downloadUrl" label="资源下载链接">
-						<el-input v-model="formData.downloadUrl"> </el-input>
-					</el-form-item>
-					<el-form-item prop="version" label="版本编号">
-						<el-input v-model="formData.version"> </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="108px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 800px"
+                >
+                    <el-form-item prop="downloadUrl" label="资源下载链接">
+                        <el-input v-model="formData.downloadUrl"> </el-input>
+                    </el-form-item>
+                    <el-form-item prop="version" label="版本编号">
+                        <el-input v-model="formData.version"> </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>
 <script>
 export default {
-	name: 'MetaResourceVersionEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaResourceVersion/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: {
-				downloadUrl: [
-					{
-						required: true,
-						message: '请输入下载链接',
-						trigger: 'blur'
-					}
-				],
-				version: [
-					{
-						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('/metaResourceVersion/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(`/metaResourceVersion/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 || '删除失败');
-					}
-				});
-		}
-	}
+    name: 'MetaResourceVersionEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaResourceVersion/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: {
+                downloadUrl: [
+                    {
+                        required: true,
+                        message: '请输入下载链接',
+                        trigger: 'blur'
+                    }
+                ],
+                version: [
+                    {
+                        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('/metaResourceVersion/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(`/metaResourceVersion/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>

+ 159 - 159
src/main/vue/src/views/MetaResourceVersionList.vue

@@ -1,61 +1,61 @@
 <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>
+    <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="createdAt" label="创建时间"> </el-table-column>
-			<el-table-column prop="downloadUrl" label="资源下载链接"> </el-table-column>
-			<el-table-column prop="version" 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>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div class="pagination-wrapper">
-			<!-- <div class="multiple-mode-wrapper">
+            <el-table-column prop="downloadUrl" label="资源下载链接"> </el-table-column>
+            <el-table-column prop="version" 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>
+                </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>
@@ -63,115 +63,115 @@
                     <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-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: 'MetaResourceVersionList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaResourceVersion/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: '/metaResourceVersionEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaResourceVersionEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaResourceVersion/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaResourceVersion/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaResourceVersionList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaResourceVersion/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: '/metaResourceVersionEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaResourceVersionEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaResourceVersion/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaResourceVersion/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 106 - 106
src/main/vue/src/views/MetaShowRoomAssetList.vue

@@ -1,119 +1,119 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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="userId" align="center" label="所属用户Id"> </el-table-column>
-			<el-table-column prop="showRoomId" align="center" label="展厅id"> </el-table-column>
-			<el-table-column prop="spaceId" align="center" label="空间id"> </el-table-column>
-			<el-table-column prop="assetId" align="center" label="资产id"> </el-table-column>
+    <div class="list-view">
+        <page-title>
+            <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="userId" align="center" label="所属用户Id"> </el-table-column>
+            <el-table-column prop="showRoomId" align="center" label="展厅id"> </el-table-column>
+            <el-table-column prop="spaceId" align="center" label="空间id"> </el-table-column>
+            <el-table-column prop="assetId" align="center" label="资产id"> </el-table-column>
             <el-table-column prop="coordinate" align="center" label="展厅内坐标">
                 <template slot-scope="{ row }">
-					{{ 'x=' + row.coordinate.x + ' , ' + 'y=' + row.coordinate.y + ' , ' + 'z=' + row.coordinate.z }} 
-				</template>
+                    {{ 'x=' + row.coordinate.x + ' , ' + 'y=' + row.coordinate.y + ' , ' + 'z=' + row.coordinate.z }}
+                </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>
+        </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaShowRoomAssetList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaShowRoomAsset/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();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaShowRoomAsset/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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);
-				});
-		}
-	}
+    name: 'MetaShowRoomAssetList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaShowRoomAsset/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();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaShowRoomAsset/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 22 - 0
src/main/vue/src/views/MetaSpatialInfoEdit.vue

@@ -51,6 +51,10 @@
                     <el-form-item prop="sale" label="挂售">
                         <el-switch v-model="formData.sale"> </el-switch>
                     </el-form-item>
+                    <el-form-item prop="type" label="空间类型">
+                        <el-input-number type="type" v-model="formData.type" :step="1" :min="1"> </el-input-number>
+                        <div class="tip">输入规则:正整数,最小为1</div>
+                    </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">
@@ -88,7 +92,25 @@ export default {
         return {
             saving: false,
             formData: {},
+            reg: /^[1-9]\d*$/,
             rules: {
+                type: [
+                    {
+                        required: true,
+                        message: '请输入空间类型',
+                        trigger: 'blur'
+                    },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!this.reg.test(value)) {
+                                callback(new Error('空间类型必须为大于1的整数'));
+                                return;
+                            } else {
+                                callback();
+                            }
+                        }
+                    }
+                ],
                 region: [
                     {
                         required: true,

+ 189 - 188
src/main/vue/src/views/MetaSpatialInfoList.vue

@@ -1,73 +1,73 @@
 <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="region" label="所属区域" :formatter="regionFormatter"> </el-table-column>
-			<el-table-column prop="coordinate" label="区域内坐标">
+    <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="region" label="所属区域" :formatter="regionFormatter"> </el-table-column>
+            <el-table-column prop="coordinate" label="区域内坐标">
                 <template slot-scope="{ row }">
-					{{ 'x=' + row.coordinate.x + ' , ' + 'y=' + row.coordinate.y + ' , ' + 'z=' + row.coordinate.z }} 
-				</template>
+                    {{ 'x=' + row.coordinate.x + ' , ' + 'y=' + row.coordinate.y + ' , ' + 'z=' + row.coordinate.z }}
+                </template>
             </el-table-column>
-			<el-table-column prop="sale" label="状态">
-				<template slot-scope="{ row }">
-					{{ row.sale ? '可售' : '未售' }} 
-				</template>
-			</el-table-column>
-			<el-table-column prop="userId" label="所属用户id"> </el-table-column>
-			<el-table-column prop="size" label="空间大小"> </el-table-column>
-			<el-table-column prop="assetId" label="资产id"> </el-table-column>
-			<el-table-column prop="hcTxHash" label="hash" width="550"> </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-table-column prop="sale" label="状态">
+                <template slot-scope="{ row }">
+                    {{ row.sale ? '可售' : '未售' }}
+                </template>
+            </el-table-column>
+            <el-table-column prop="userId" label="所属用户id"> </el-table-column>
+            <el-table-column prop="size" label="空间大小"> </el-table-column>
+            <el-table-column prop="assetId" label="资产id"> </el-table-column>
+            <el-table-column prop="hcTxHash" label="hash" width="550"> </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>
@@ -75,134 +75,135 @@
                     <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-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: 'MetaSpatialInfoList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaSpatialInfo/all',
-			downloading: false,
-			regionOptions: [
-				{ label: '1区', value: 'ONE' },
-				{ label: '2区', value: 'TWO' },
-				{ label: '3区', value: 'THREE' },
-				{ label: '4区', value: 'FOUR' },
-				{ label: '5区', value: 'FIVE' },
-				{ label: '6区', value: 'SIX' },
-				{ label: '7区', value: 'SEVEN' },
-				{ label: '8区', value: 'EIGHT' },
-				{ label: '9区', value: 'NINE' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		regionFormatter(row, column, cellValue, index) {
-			let selectedOption = this.regionOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false }, sort:'id,asc' };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaSpatialInfoEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaSpatialInfoEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaSpatialInfo/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaSpatialInfo/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaSpatialInfoList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaSpatialInfo/all',
+            downloading: false,
+            regionOptions: [
+                { label: '1区', value: 'ONE' },
+                { label: '2区', value: 'TWO' },
+                { label: '3区', value: 'THREE' },
+                { label: '4区', value: 'FOUR' },
+                { label: '5区', value: 'FIVE' },
+                { label: '6区', value: 'SIX' },
+                { label: '7区', value: 'SEVEN' },
+                { label: '8区', value: 'EIGHT' },
+                { label: '9区', value: 'NINE' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        regionFormatter(row, column, cellValue, index) {
+            let selectedOption = this.regionOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false }, sort: 'id,asc' };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaSpatialInfoEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaSpatialInfoEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaSpatialInfo/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaSpatialInfo/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>

+ 139 - 0
src/main/vue/src/views/MetaSpatialWharfList.vue

@@ -0,0 +1,139 @@
+<template>
+    <div class="list-view">
+        <page-title>
+            <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="isLandId" align="center" label="岛屿ID"> </el-table-column>
+            <el-table-column prop="boatId" align="center" label="船只ID"> </el-table-column>
+			<el-table-column prop="userId" align="center" label="所属用户"> </el-table-column>
+            <el-table-column prop="boatImg" align="center" label="船只图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.boatImg"
+                        fit="cover"
+                        :preview-src-list="[row.boatImg]"
+                    >
+                    </el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="boatType" align="center" label="船只类型">
+            </el-table-column>
+            <el-table-column prop="boatPos" align="center" label="位置信息">
+                <template slot-scope="{ row }">
+                    {{ 'x=' + row.boatPos.x + ' , ' + 'y=' + row.boatPos.y + ' , ' + 'z=' + row.boatPos.z }}
+                </template>
+            </el-table-column>
+            <el-table-column prop="boatRot" align="center" label="旋转值">
+                <template slot-scope="{ row }">
+                    {{ 'x=' + row.boatRot.x + ' , ' + 'y=' + row.boatRot.y + ' , ' + 'z=' + row.boatRot.z }}
+                </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>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+    name: 'MetaSpatialWharfList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaSpatialWharf/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();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaSpatialWharf/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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);
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+
+</style>

+ 136 - 136
src/main/vue/src/views/MetaTaskActivityEdit.vue

@@ -1,144 +1,144 @@
 <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="word" label="文字">
-                        <el-input v-model="formData.word" type="textarea"> </el-input>
-                    </el-form-item>
-                    <el-form-item prop="picture" label="图片">
-                        <single-upload v-model="formData.picture"> </single-upload>
-                    </el-form-item>
-                    <el-form-item prop="link" label="链接地址">
-                        <el-input v-model="formData.link"> </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>
+	<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="word" label="文字">
+						<el-input v-model="formData.word" type="textarea"> </el-input>
+					</el-form-item>
+					<el-form-item prop="picture" label="图片">
+						<single-upload v-model="formData.picture"> </single-upload>
+					</el-form-item>
+					<el-form-item prop="link" label="链接地址">
+						<el-input v-model="formData.link"> </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: 'MetaTaskActivityEdit',
-    created() {
-        if (this.$route.query.id) {
-            this.$http
-                .get('metaTaskActivity/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'
-                    }
-                ],
-                word: [
-                    {
-                        required: true,
-                        message: '请输入文字',
-                        trigger: 'blur'
-                    }
-                ],
-                picture: [
-                    {
-                        required: true,
-                        message: '请输入图片',
-                        trigger: 'blur'
-                    }
-                ],
-                link: [
-                    {
-                        required: true,
-                        message: '请输入链接地址',
-                        trigger: 'blur'
-                    }
-                ]
-            }
-        };
-    },
-    methods: {
-        onSave() {
-            this.$refs.form.validate(valid => {
-                if (valid) {
-                    this.submit();
-                } else {
-                    return false;
-                }
-            });
-        },
-        submit() {
-            let data = { ...this.formData };
+	name: 'MetaTaskActivityEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaTaskActivity/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'
+					}
+				],
+				word: [
+					{
+						required: true,
+						message: '请输入文字',
+						trigger: 'blur'
+					}
+				],
+				picture: [
+					{
+						required: true,
+						message: '请输入图片',
+						trigger: 'blur'
+					}
+				],
+				link: [
+					{
+						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('/metaTaskActivity/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(`/metaTaskActivity/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('/metaTaskActivity/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(`/metaTaskActivity/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>

+ 176 - 176
src/main/vue/src/views/MetaTaskActivityList.vue

@@ -1,77 +1,77 @@
 <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="word" label="文字"> </el-table-column>
-			<el-table-column prop="picture" label="图片">
-				<template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.picture"
-						fit="cover"
-						:preview-src-list="[row.picture]"
-					>
-					</el-image>
-				</template>
-			</el-table-column>
-			<el-table-column prop="link" label="链接地址"> </el-table-column>
-			<el-table-column prop="publish" 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">
+    <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="word" label="文字"> </el-table-column>
+            <el-table-column prop="picture" label="图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.picture"
+                        fit="cover"
+                        :preview-src-list="[row.picture]"
+                    >
+                    </el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="link" label="链接地址"> </el-table-column>
+            <el-table-column prop="publish" 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>
@@ -79,115 +79,115 @@
                     <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-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: 'MetaTaskActivityList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaTaskActivity/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: '/metaTaskActivityEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaTaskActivityEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaTaskActivity/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaTaskActivity/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaTaskActivityList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaTaskActivity/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: '/metaTaskActivityEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaTaskActivityEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaTaskActivity/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaTaskActivity/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 265 - 265
src/main/vue/src/views/MetaTaskEdit.vue

@@ -1,273 +1,273 @@
 <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="130px"
-					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="detail" label="详情" style="width: calc(100vw - 450px)">
-						<el-input
-							v-model="formData.detail"
-							type="textarea"
-							:autosize="{ minRows: 3, maxRows: 20 }"
-							placeholder="请输入任务详情"
-						>
-						</el-input>
-					</el-form-item>
-					<el-form-item prop="awardType" label="奖励类型">
-						<el-select
-							v-model="formData.awardType"
-							clearable
-							filterable
-							placeholder="请选择"
-							@change="changeAwardType"
-						>
-							<el-option
-								v-for="item in awardTypeOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<el-form-item
-						prop="awardPic"
-						label="奖励图片"
-						v-if="formData.awardType && formData.awardType === 'NFT'"
-					>
-						<single-upload v-model="formData.awardPic"> </single-upload>
-					</el-form-item>
-					<el-form-item
-						prop="goldNum"
-						label="奖励金币数量"
-						v-if="formData.awardType && formData.awardType === 'GOLD'"
-					>
-						<el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
-						</el-input-number>
-						<div class="tip">输入规则:正整数,最小为1</div>
-					</el-form-item>
-					<el-form-item prop="type" label="任务类型">
-						<el-select v-model="formData.type" clearable filterable placeholder="请选择" @change="change">
-							<el-option
-								v-for="item in typeOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-					</el-form-item>
-					<template v-if="formData.type">
-						<el-form-item v-if="formData.type === 'SIGN_IN_SINGLE_DAY'" prop="value" label="签到日期">
-							<el-date-picker
-								v-model="formData.value"
-								type="date"
-								value-format="yyyy-MM-dd"
-								placeholder="指定签到日期"
-							>
-							</el-date-picker>
-						</el-form-item>
-						<el-form-item v-if="formData.type === 'SIGN_IN_CONTINUOUS'" prop="value" label="开始日期">
-							<el-date-picker
-								v-model="formData.value"
-								type="date"
-								value-format="yyyy-MM-dd"
-								placeholder="指定开始日期"
-							>
-							</el-date-picker>
-						</el-form-item>
-						<el-form-item prop="value" label="藏品id" v-if="formData.type === 'COLLECT_COLLECTION'">
-							<el-input v-model="formData.value" placeholder="请输入定藏品id"> </el-input>
-							<div class="tip">多个藏品id请用空格隔开 例如 111 222 333</div>
-						</el-form-item>
-						<el-form-item prop="value" label="次数" v-if="formData.type === 'ACCUMULATE'">
-							<el-input-number v-model="formData.value" :min="0"> </el-input-number>
-						</el-form-item>
-						<el-form-item prop="value" label="在线时长(min)" v-if="formData.type === 'ON_LINE_TIME_DAILY'">
-							<el-input-number v-model="formData.value" :min="0"> </el-input-number>
-						</el-form-item>
-					</template>
-					<el-form-item prop="publish" label="是否发布">
-						<el-switch v-model="formData.publish"> </el-switch>
-					</el-form-item>
-					<el-form-item prop="mark" label="是否展示角标">
-						<el-switch v-model="formData.mark"> </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>
+    <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="130px"
+                    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="detail" label="详情" style="width: calc(100vw - 450px)">
+                        <el-input
+                            v-model="formData.detail"
+                            type="textarea"
+                            :autosize="{ minRows: 3, maxRows: 20 }"
+                            placeholder="请输入任务详情"
+                        >
+                        </el-input>
+                    </el-form-item>
+                    <el-form-item prop="awardType" label="奖励类型">
+                        <el-select
+                            v-model="formData.awardType"
+                            clearable
+                            filterable
+                            placeholder="请选择"
+                            @change="changeAwardType"
+                        >
+                            <el-option
+                                v-for="item in awardTypeOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item
+                        prop="awardPic"
+                        label="奖励图片"
+                        v-if="formData.awardType && formData.awardType === 'NFT'"
+                    >
+                        <single-upload v-model="formData.awardPic"> </single-upload>
+                    </el-form-item>
+                    <el-form-item
+                        prop="goldNum"
+                        label="奖励金币数量"
+                        v-if="formData.awardType && formData.awardType === 'GOLD'"
+                    >
+                        <el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
+                        </el-input-number>
+                        <div class="tip">输入规则:正整数,最小为1</div>
+                    </el-form-item>
+                    <el-form-item prop="type" label="任务类型">
+                        <el-select v-model="formData.type" clearable filterable placeholder="请选择" @change="change">
+                            <el-option
+                                v-for="item in typeOptions"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <template v-if="formData.type">
+                        <el-form-item v-if="formData.type === 'SIGN_IN_SINGLE_DAY'" prop="value" label="签到日期">
+                            <el-date-picker
+                                v-model="formData.value"
+                                type="date"
+                                value-format="yyyy-MM-dd"
+                                placeholder="指定签到日期"
+                            >
+                            </el-date-picker>
+                        </el-form-item>
+                        <el-form-item v-if="formData.type === 'SIGN_IN_CONTINUOUS'" prop="value" label="开始日期">
+                            <el-date-picker
+                                v-model="formData.value"
+                                type="date"
+                                value-format="yyyy-MM-dd"
+                                placeholder="指定开始日期"
+                            >
+                            </el-date-picker>
+                        </el-form-item>
+                        <el-form-item prop="value" label="藏品id" v-if="formData.type === 'COLLECT_COLLECTION'">
+                            <el-input v-model="formData.value" placeholder="请输入定藏品id"> </el-input>
+                            <div class="tip">多个藏品id请用空格隔开 例如 111 222 333</div>
+                        </el-form-item>
+                        <el-form-item prop="value" label="次数" v-if="formData.type === 'ACCUMULATE'">
+                            <el-input-number v-model="formData.value" :min="0"> </el-input-number>
+                        </el-form-item>
+                        <el-form-item prop="value" label="在线时长(min)" v-if="formData.type === 'ON_LINE_TIME_DAILY'">
+                            <el-input-number v-model="formData.value" :min="0"> </el-input-number>
+                        </el-form-item>
+                    </template>
+                    <el-form-item prop="publish" label="是否发布">
+                        <el-switch v-model="formData.publish"> </el-switch>
+                    </el-form-item>
+                    <el-form-item prop="mark" label="是否展示角标">
+                        <el-switch v-model="formData.mark"> </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: 'MetaTaskEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaTask/get/' + this.$route.query.id)
-				.then(res => {
-					this.formData = res;
-				})
-				.catch(e => {
-					console.log(e);
-					this.$message.error(e.error);
-				});
-		}
-	},
-	data() {
-		return {
-			reg: /^[1-9]\d*$/,
-			saving: false,
-			formData: {},
-			rules: {
-				name: [
-					{
-						required: true,
-						message: '请输入任务名称',
-						trigger: 'blur'
-					}
-				],
-				detail: [
-					{
-						required: true,
-						message: '请输入任务详情',
-						trigger: 'blur'
-					}
-				],
-				type: [
-					{
-						required: true,
-						message: '请输入任务类型',
-						trigger: 'blur'
-					}
-				],
-				value: [
-					{
-						required: true,
-						message: '请指定参数配置',
-						trigger: 'blur'
-					}
-				],
-				goldNum: [
-					{
-						required: true,
-						message: '请输入奖励金币数量',
-						trigger: 'blur'
-					},
-					{
-						validator: (rule, value, callback) => {
-							if (!this.reg.test(value)) {
-								callback(new Error('奖励金币数量必须为大于1的整数'));
-								return;
-							} else {
-								callback();
-							}
-						}
-					}
-				],
-				awardType: [
-					{
-						required: true,
-						message: '请选择奖励类型',
-						trigger: 'blur'
-					}
-				],
-				awardPic: [
-					{
-						required: true,
-						message: '请上传奖励图片',
-						trigger: 'blur'
-					}
-				]
-			},
-			typeOptions: [
-				{ label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
-				{ label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
-				{ label: '收集藏品', value: 'COLLECT_COLLECTION' },
-				{ label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
-				{ label: '累计', value: 'ACCUMULATE' }
-			],
-			awardTypeOptions: [
-				{ label: 'NFT', value: 'NFT' },
-				{ label: '金币', value: 'GOLD' }
-			]
-		};
-	},
-	methods: {
-		changeAwardType(row) {
-			this.$delete(this.formData, 'awardPic');
-			this.$delete(this.formData, 'goldNum');
-		},
-		change() {
-			if (this.formData.value) {
-				this.$delete(this.formData, 'value');
-			}
-		},
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+    name: 'MetaTaskEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaTask/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            reg: /^[1-9]\d*$/,
+            saving: false,
+            formData: {},
+            rules: {
+                name: [
+                    {
+                        required: true,
+                        message: '请输入任务名称',
+                        trigger: 'blur'
+                    }
+                ],
+                detail: [
+                    {
+                        required: true,
+                        message: '请输入任务详情',
+                        trigger: 'blur'
+                    }
+                ],
+                type: [
+                    {
+                        required: true,
+                        message: '请输入任务类型',
+                        trigger: 'blur'
+                    }
+                ],
+                value: [
+                    {
+                        required: true,
+                        message: '请指定参数配置',
+                        trigger: 'blur'
+                    }
+                ],
+                goldNum: [
+                    {
+                        required: true,
+                        message: '请输入奖励金币数量',
+                        trigger: 'blur'
+                    },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (!this.reg.test(value)) {
+                                callback(new Error('奖励金币数量必须为大于1的整数'));
+                                return;
+                            } else {
+                                callback();
+                            }
+                        }
+                    }
+                ],
+                awardType: [
+                    {
+                        required: true,
+                        message: '请选择奖励类型',
+                        trigger: 'blur'
+                    }
+                ],
+                awardPic: [
+                    {
+                        required: true,
+                        message: '请上传奖励图片',
+                        trigger: 'blur'
+                    }
+                ]
+            },
+            typeOptions: [
+                { label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
+                { label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
+                { label: '收集藏品', value: 'COLLECT_COLLECTION' },
+                { label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
+                { label: '累计', value: 'ACCUMULATE' }
+            ],
+            awardTypeOptions: [
+                { label: 'NFT', value: 'NFT' },
+                { label: '金币', value: 'GOLD' }
+            ]
+        };
+    },
+    methods: {
+        changeAwardType(row) {
+            this.$delete(this.formData, 'awardPic');
+            this.$delete(this.formData, 'goldNum');
+        },
+        change() {
+            if (this.formData.value) {
+                this.$delete(this.formData, 'value');
+            }
+        },
+        onSave() {
+            this.$refs.form.validate(valid => {
+                if (valid) {
+                    this.submit();
+                } else {
+                    return false;
+                }
+            });
+        },
+        submit() {
+            let data = { ...this.formData };
 
-			this.saving = true;
-			this.$http
-				.post('/metaTask/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(`/metaTask/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('/metaTask/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(`/metaTask/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>

+ 238 - 238
src/main/vue/src/views/MetaTaskList.vue

@@ -1,248 +1,248 @@
 <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="createdAt" label="创建时间"> </el-table-column>
-            <el-table-column prop="name" label="任务名称"> </el-table-column>
-            <el-table-column prop="type" label="任务类型" :formatter="typeFormatter"> </el-table-column>
-            <el-table-column prop="value" label="配置值"> </el-table-column>
-            <el-table-column prop="detail" label="详情"> </el-table-column>
-            <el-table-column prop="awardType" label="奖励类型" :formatter="awardTypeFormatter"> </el-table-column>
-            <el-table-column prop="awardPic" label="奖励图片">
-                <template slot-scope="{ row }">
-                    <el-image
-                        style="width: 30px; height: 30px"
-                        :src="row.awardPic"
-                        fit="cover"
-                        :preview-src-list="[row.awardPic]"
-                    >
-                    </el-image>
-                </template>
-            </el-table-column>
-            <el-table-column prop="goldNum" label="奖励金币数量"> </el-table-column>
-            <el-table-column prop="publish" label="是否发布">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.publish ? '' : 'info'"> {{ row.publish }} </el-tag>
-                </template>
-            </el-table-column>
-            <el-table-column prop="mark" label="是否展示角标">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.mark ? '' : 'info'"> {{ row.mark }} </el-tag>
-                </template>
-            </el-table-column>
-            <el-table-column prop="finish" label="是否结束">
-                <template slot-scope="{ row }">
-                    <el-tag :type="row.finish ? '' : 'info'"> {{ row.finish }} </el-tag>
-                </template>
-            </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" width="250">
-                <template slot-scope="{ row }">
-                    <el-button @click="editRow(row)" type="primary" size="mini" plain v-if="!row.finish">
-                        编辑
-                    </el-button>
-                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain> 删除 </el-button>
-                    <el-button @click="finish(row)" type="danger" size="mini" plain v-if="!row.finish">
-                        结束任务
-                    </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>
+	<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="createdAt" label="创建时间"> </el-table-column>
+			<el-table-column prop="name" label="任务名称"> </el-table-column>
+			<el-table-column prop="type" label="任务类型" :formatter="typeFormatter"> </el-table-column>
+			<el-table-column prop="value" label="配置值"> </el-table-column>
+			<el-table-column prop="detail" label="详情"> </el-table-column>
+			<el-table-column prop="awardType" label="奖励类型" :formatter="awardTypeFormatter"> </el-table-column>
+			<el-table-column prop="awardPic" label="奖励图片">
+				<template slot-scope="{ row }">
+					<el-image
+						style="width: 30px; height: 30px"
+						:src="row.awardPic"
+						fit="cover"
+						:preview-src-list="[row.awardPic]"
+					>
+					</el-image>
+				</template>
+			</el-table-column>
+			<el-table-column prop="goldNum" label="奖励金币数量"> </el-table-column>
+			<el-table-column prop="publish" label="是否发布">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.publish ? '' : 'info'"> {{ row.publish }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="mark" label="是否展示角标">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.mark ? '' : 'info'"> {{ row.mark }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column prop="finish" label="是否结束">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.finish ? '' : 'info'"> {{ row.finish }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column label="操作" align="center" fixed="right" width="250">
+				<template slot-scope="{ row }">
+					<el-button @click="editRow(row)" type="primary" size="mini" plain v-if="!row.finish">
+						编辑
+					</el-button>
+					<el-button @click="deleteRow(row)" type="danger" size="mini" plain> 删除 </el-button>
+					<el-button @click="finish(row)" type="danger" size="mini" plain v-if="!row.finish">
+						结束任务
+					</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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-    name: 'MetaTaskList',
-    mixins: [pageableTable],
-    data() {
-        return {
-            multipleMode: false,
-            search: '',
-            url: '/metaTask/all',
-            downloading: false,
-            typeOptions: [
-                { label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
-                { label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
-                { label: '收集藏品', value: 'COLLECT_COLLECTION' },
-                { label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
-                { label: '累计', value: 'ACCUMULATE' }
-            ],
-            awardTypeOptions: [
-                { label: 'NFT', value: 'NFT' },
-                { label: '金币', value: 'GOLD' }
-            ]
-        };
-    },
-    computed: {
-        selection() {
-            return this.$refs.table.selection.map(i => i.id);
-        }
-    },
-    methods: {
-        typeFormatter(row, column, cellValue, index) {
-            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
-            if (selectedOption) {
-                return selectedOption.label;
-            }
-            return '';
-        },
-        awardTypeFormatter(row, column, cellValue, index) {
-            let selectedOption = this.awardTypeOptions.find(i => i.value === cellValue);
-            if (selectedOption) {
-                return selectedOption.label;
-            }
-            return '';
-        },
-        beforeGetData() {
-            return { search: this.search, query: { del: false } };
-        },
-        toggleMultipleMode(multipleMode) {
-            this.multipleMode = multipleMode;
-            if (!multipleMode) {
-                this.$refs.table.clearSelection();
-            }
-        },
-        addRow() {
-            this.$router.push({
-                path: '/metaTaskEdit',
-                query: {
-                    ...this.$route.query
-                }
-            });
-        },
-        editRow(row) {
-            this.$router.push({
-                path: '/metaTaskEdit',
-                query: {
-                    id: row.id
-                }
-            });
-        },
-        download() {
-            this.downloading = true;
-            this.$axios
-                .get('/metaTask/excel', {
-                    responseType: 'blob',
-                    params: { size: 10000, query: { del: false } }
-                })
-                .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) {
-            if (!row.finish) {
-                this.$alert('请先结束任务!', '警告', { type: 'error' });
-                return;
-            }
-            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
-                .then(() => {
-                    return this.$http.post(`/metaTask/del/${row.id}`);
-                })
-                .then(() => {
-                    this.$message.success('删除成功');
-                    this.getData();
-                })
-                .catch(e => {
-                    if (e !== 'cancel') {
-                        this.$message.error(e.error);
-                    }
-                });
-        },
-        finish(row) {
-            this.$alert('任务结束后在不能再被领取,确定要结束任务吗?', '警告', { type: 'error' })
-                .then(() => {
-                    return this.$http.post(`/metaTask/${row.id}/finish`);
-                })
-                .then(() => {
-                    this.$message.success('结束成功');
-                    this.getData();
-                })
-                .catch(e => {
-                    if (e !== 'cancel') {
-                        this.$message.error(e.error);
-                    }
-                });
-        }
-    }
+	name: 'MetaTaskList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			multipleMode: false,
+			search: '',
+			url: '/metaTask/all',
+			downloading: false,
+			typeOptions: [
+				{ label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
+				{ label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
+				{ label: '收集藏品', value: 'COLLECT_COLLECTION' },
+				{ label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
+				{ label: '累计', value: 'ACCUMULATE' }
+			],
+			awardTypeOptions: [
+				{ label: 'NFT', value: 'NFT' },
+				{ label: '金币', value: 'GOLD' }
+			]
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		typeFormatter(row, column, cellValue, index) {
+			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+			if (selectedOption) {
+				return selectedOption.label;
+			}
+			return '';
+		},
+		awardTypeFormatter(row, column, cellValue, index) {
+			let selectedOption = this.awardTypeOptions.find(i => i.value === cellValue);
+			if (selectedOption) {
+				return selectedOption.label;
+			}
+			return '';
+		},
+		beforeGetData() {
+			return { search: this.search, query: { del: false } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		addRow() {
+			this.$router.push({
+				path: '/metaTaskEdit',
+				query: {
+					...this.$route.query
+				}
+			});
+		},
+		editRow(row) {
+			this.$router.push({
+				path: '/metaTaskEdit',
+				query: {
+					id: row.id
+				}
+			});
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaTask/excel', {
+					responseType: 'blob',
+					params: { size: 10000, query: { del: false } }
+				})
+				.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) {
+			if (!row.finish) {
+				this.$alert('请先结束任务!', '警告', { type: 'error' });
+				return;
+			}
+			this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaTask/del/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('删除成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		},
+		finish(row) {
+			this.$alert('任务结束后在不能再被领取,确定要结束任务吗?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaTask/${row.id}/finish`);
+				})
+				.then(() => {
+					this.$message.success('结束成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		}
+	}
 };
 </script>
 <style lang="less" scoped>

+ 145 - 145
src/main/vue/src/views/MetaTaskToUserList.vue

@@ -1,157 +1,157 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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"> </el-table-column>
+    <div class="list-view">
+        <page-title>
+            <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"> </el-table-column>
             <el-table-column prop="userId" label="用户id"> </el-table-column>
             <el-table-column prop="getTime" label="领取时间"> </el-table-column>
-			<el-table-column prop="finishTime" label="完成时间"> </el-table-column>
-			<el-table-column prop="taskId" label="任务id"> </el-table-column>
-			<el-table-column prop="taskName" label="任务名称"> </el-table-column>
-			<el-table-column prop="detail" label="详情"> </el-table-column>
-			<el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormatter"> </el-table-column>
-			<el-table-column prop="status" label="当前状态" :formatter="taskStatusFormatter"> </el-table-column>
-			<el-table-column prop="awardPic" label="奖励图片">
-				<template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.awardPic"
-						fit="cover"
-						:preview-src-list="[row.awardPic]"
-					>
-					</el-image>
-				</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>
+            <el-table-column prop="finishTime" label="完成时间"> </el-table-column>
+            <el-table-column prop="taskId" label="任务id"> </el-table-column>
+            <el-table-column prop="taskName" label="任务名称"> </el-table-column>
+            <el-table-column prop="detail" label="详情"> </el-table-column>
+            <el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormatter"> </el-table-column>
+            <el-table-column prop="status" label="当前状态" :formatter="taskStatusFormatter"> </el-table-column>
+            <el-table-column prop="awardPic" label="奖励图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.awardPic"
+                        fit="cover"
+                        :preview-src-list="[row.awardPic]"
+                    >
+                    </el-image>
+                </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaTaskToUserList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaTaskToUser/all',
-			downloading: false,
-			taskTypeOptions: [
-				{ label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
-				{ label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
-				{ label: '收集藏品', value: 'COLLECT_COLLECTION' },
-				{ label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
-				{ label: '累计', value: 'ACCUMULATE' }
-			],
-			taskStatusOptions: [
-				{ label: '领取', value: 'GET' },
-				{ label: '进行中', value: 'PROGRESS' },
-				{ label: '已完成', value: 'COMPLETION' },
-				{ label: '已结束', value: 'FINISH' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		taskTypeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.taskTypeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		taskStatusFormatter(row, column, cellValue, index) {
-			let selectedOption = this.taskStatusOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaTaskToUser/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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);
-				});
-		}
-	}
+    name: 'MetaTaskToUserList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaTaskToUser/all',
+            downloading: false,
+            taskTypeOptions: [
+                { label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
+                { label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
+                { label: '收集藏品', value: 'COLLECT_COLLECTION' },
+                { label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
+                { label: '累计', value: 'ACCUMULATE' }
+            ],
+            taskStatusOptions: [
+                { label: '领取', value: 'GET' },
+                { label: '进行中', value: 'PROGRESS' },
+                { label: '已完成', value: 'COMPLETION' },
+                { label: '已结束', value: 'FINISH' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        taskTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.taskTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        taskStatusFormatter(row, column, cellValue, index) {
+            let selectedOption = this.taskStatusOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaTaskToUser/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 101 - 100
src/main/vue/src/views/MetaUserEdit.vue

@@ -1,61 +1,61 @@
 <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="108px"
-					label-position="right"
-					size="small"
-					style="max-width: 500px"
-				>
-					<el-form-item prop="phone" label="用户手机号">
-						<el-input type="number" v-model="formData.phone"> </el-input>
-					</el-form-item>
-					<el-form-item prop="allowLogin" label="是否允许登陆">
-						<el-switch v-model="formData.allowLogin"> </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>
+    <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="108px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px"
+                >
+                    <el-form-item prop="phone" label="用户手机号">
+                        <el-input type="number" v-model="formData.phone"> </el-input>
+                    </el-form-item>
+                    <el-form-item prop="allowLogin" label="是否允许登陆">
+                        <el-switch v-model="formData.allowLogin"> </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: 'MetaUserEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaUser/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: {
-				phone: [
+    name: 'MetaUserEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaUser/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: {
+                phone: [
                     {
                         required: true,
                         message: '请输入手机号',
@@ -67,54 +67,55 @@ export default {
                         trigger: 'blur'
                     }
                 ]
-			}
-		};
-	},
-	methods: {
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+            }
+        };
+    },
+    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('/metaUser/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(`/metaUser/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('/metaUser/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(`/metaUser/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>

+ 195 - 195
src/main/vue/src/views/MetaUserGoldList.vue

@@ -1,207 +1,207 @@
 <template>
-    <div class="list-view">
-        <page-title>
-            <el-button @click="addUserIds" type="primary" 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 prop="id" align="center" label="ID" width="100"> </el-table-column>
-            <el-table-column prop="userId" align="center" label="玩家id"> </el-table-column>
-            <el-table-column prop="num" align="center" label="当前金币数量"> </el-table-column>
-        </el-table>
-        <el-dialog :visible.sync="showUserIdDialog" title="添加用户id" width="600px" :close-on-click-modal="false">
-            <el-form ref="userIdForm">
-                <el-form-item :rules="[{ required: true, message: '请输入用户id' }]">
-                    <el-input
-                        v-model="userIds"
-                        type="textarea"
-                        :autosize="{ minRows: 3, maxRows: 20 }"
-                        placeholder="可输入多个用户id,用空格分隔"
-                    >
-                    </el-input>
-                </el-form-item>
-            </el-form>
-            <div slot="footer">
-                <el-button @click="showUserIdDialog = false" size="mini"> 取消 </el-button>
-                <el-button @click="initUserGold" size="mini" :loading="loading" type="primary"> 确定 </el-button>
-            </div>
-        </el-dialog>
-        <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>
+	<div class="list-view">
+		<page-title>
+			<el-button @click="addUserIds" type="primary" 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 prop="id" align="center" label="ID" width="100"> </el-table-column>
+			<el-table-column prop="userId" align="center" label="玩家id"> </el-table-column>
+			<el-table-column prop="num" align="center" label="当前金币数量"> </el-table-column>
+		</el-table>
+		<el-dialog :visible.sync="showUserIdDialog" title="添加用户id" width="600px" :close-on-click-modal="false">
+			<el-form ref="userIdForm">
+				<el-form-item :rules="[{ required: true, message: '请输入用户id' }]">
+					<el-input
+						v-model="userIds"
+						type="textarea"
+						:autosize="{ minRows: 3, maxRows: 20 }"
+						placeholder="可输入多个用户id,用空格分隔"
+					>
+					</el-input>
+				</el-form-item>
+			</el-form>
+			<div slot="footer">
+				<el-button @click="showUserIdDialog = false" size="mini"> 取消 </el-button>
+				<el-button @click="initUserGold" size="mini" :loading="loading" type="primary"> 确定 </el-button>
+			</div>
+		</el-dialog>
+		<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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-    name: 'MetaUserGoldList',
-    mixins: [pageableTable],
-    data() {
-        return {
-            loading: false,
-            showUserIdDialog: false,
-            userIds: '',
-            multipleMode: false,
-            search: '',
-            url: '/metaUserGold/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: '/metaUserGoldEdit',
-                query: {
-                    ...this.$route.query
-                }
-            });
-        },
-        editRow(row) {
-            this.$router.push({
-                path: '/metaUserGoldEdit',
-                query: {
-                    id: row.id
-                }
-            });
-        },
-        download() {
-            this.downloading = true;
-            this.$axios
-                .get('/metaUserGold/excel', {
-                    responseType: 'blob',
-                    params: { size: 10000 ,query: { del: false }},
-                })
-                .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);
-                });
-        },
-        addUserIds() {
-            this.userIds = '';
-            this.showUserIdDialog = true;
-            if (this.$refs.userIdForm) {
-                this.$nextTick(() => {
-                    this.$refs.userIdForm.clearValidate();
-                });
-            }
-        },
-        initUserGold() {
-            this.loading = true;
-            this.$http
-                .get(`/metaUserGold/${this.userIds}/check`)
-                .then(res => {
-                    this.$alert('确定要初始化这些用户的金币数量吗?', '提示', { type: 'info' })
-                        .then(() => {
-                            return this.$http.post(`/metaUserGold/${this.userIds}/init`);
-                        })
-                        .then(() => {
-                            this.loading = false;
-                            this.showUserIdDialog = false;
-                            this.$message.success('初始化成功');
-                            this.getData();
-                        })
-                        .catch(e => {
+	name: 'MetaUserGoldList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			loading: false,
+			showUserIdDialog: false,
+			userIds: '',
+			multipleMode: false,
+			search: '',
+			url: '/metaUserGold/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: '/metaUserGoldEdit',
+				query: {
+					...this.$route.query
+				}
+			});
+		},
+		editRow(row) {
+			this.$router.push({
+				path: '/metaUserGoldEdit',
+				query: {
+					id: row.id
+				}
+			});
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaUserGold/excel', {
+					responseType: 'blob',
+					params: { size: 10000, query: { del: false } }
+				})
+				.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);
+				});
+		},
+		addUserIds() {
+			this.userIds = '';
+			this.showUserIdDialog = true;
+			if (this.$refs.userIdForm) {
+				this.$nextTick(() => {
+					this.$refs.userIdForm.clearValidate();
+				});
+			}
+		},
+		initUserGold() {
+			this.loading = true;
+			this.$http
+				.get(`/metaUserGold/${this.userIds}/check`)
+				.then(res => {
+					this.$alert('确定要初始化这些用户的金币数量吗?', '提示', { type: 'info' })
+						.then(() => {
+							return this.$http.post(`/metaUserGold/${this.userIds}/init`);
+						})
+						.then(() => {
+							this.loading = false;
+							this.showUserIdDialog = false;
+							this.$message.success('初始化成功');
+							this.getData();
+						})
+						.catch(e => {
 							this.$message.error(e.error);
-                            this.loading = false;
-                        });
-                })
-                .catch(e => {
+							this.loading = false;
+						});
+				})
+				.catch(e => {
 					this.$message.error(e.error);
-                    this.loading = false;
-                });
-        },
-        operation1() {
-            this.$notify({
-                title: '提示',
-                message: this.selection
-            });
-        },
-        operation2() {
-            this.$message('操作2');
-        },
-        deleteRow(row) {
-            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
-                .then(() => {
-                    return this.$http.post(`/metaUserGold/del/${row.id}`);
-                })
-                .then(() => {
-                    this.$message.success('删除成功');
-                    this.getData();
-                })
-                .catch(e => {
-                    if (e !== 'cancel') {
-                        this.$message.error(e.error);
-                    }
-                });
-        }
-    }
+					this.loading = false;
+				});
+		},
+		operation1() {
+			this.$notify({
+				title: '提示',
+				message: this.selection
+			});
+		},
+		operation2() {
+			this.$message('操作2');
+		},
+		deleteRow(row) {
+			this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaUserGold/del/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('删除成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		}
+	}
 };
 </script>
 <style lang="less" scoped>

+ 150 - 150
src/main/vue/src/views/MetaUserGoldRecordList.vue

@@ -1,42 +1,42 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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 prop="id" align="center" label="ID" width="100"> </el-table-column>
-			<el-table-column prop="userId" align="center" label="用户id"> </el-table-column>
-			<el-table-column prop="createdAt" align="center" label="操作时间"> </el-table-column>
-			<el-table-column prop="beforeNum" align="center" label="操作前金币数量"> </el-table-column>
+    <div class="list-view">
+        <page-title>
+            <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 prop="id" align="center" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="userId" align="center" label="用户id"> </el-table-column>
+            <el-table-column prop="createdAt" align="center" label="操作时间"> </el-table-column>
+            <el-table-column prop="beforeNum" align="center" label="操作前金币数量"> </el-table-column>
             <el-table-column prop="operationNum" align="center" label="本次操作金币数量">
                 <template v-slot="{ row }">
                     <span :style="{ color: row.operationNum >= 0 ? '#f56c6c' : '#67c23a' }">
@@ -46,126 +46,126 @@
             </el-table-column>
             <el-table-column prop="operationNum" align="center" label="操作类型">
                 <template v-slot="{ row }">
-					<template v-if="row.beforeNum === 0 && row.operationNum === 0 && row.afterNum === 0">
-						{{ '初始化' }}
-					</template>
-					<template v-else>
-						{{ row.operationNum >= 0 ? '收入' : '支出' }}
-					</template>
+                    <template v-if="row.beforeNum === 0 && row.operationNum === 0 && row.afterNum === 0">
+                        {{ '初始化' }}
+                    </template>
+                    <template v-else>
+                        {{ row.operationNum >= 0 ? '收入' : '支出' }}
+                    </template>
                 </template>
             </el-table-column>
-			<el-table-column prop="afterNum" align="center" label="操作后金币数量"> </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>
+            <el-table-column prop="afterNum" align="center" label="操作后金币数量"> </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaUserGoldRecordList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaUserGoldRecord/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: '/metaUserGoldRecordEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaUserGoldRecordEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaUserGoldRecord/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaUserGoldRecord/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaUserGoldRecordList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaUserGoldRecord/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: '/metaUserGoldRecordEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaUserGoldRecordEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaUserGoldRecord/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaUserGoldRecord/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 156 - 155
src/main/vue/src/views/MetaUserList.vue

@@ -1,58 +1,58 @@
 <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">
+    <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="phone" label="用户手机号"> </el-table-column>
-			<el-table-column prop="allowLogin" label="是否允许登陆">
-				<template slot-scope="{ row }">
-					<el-tag :type="row.allowLogin ? '' : 'info'"> {{ row.allowLogin }} </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">
+        </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="phone" label="用户手机号"> </el-table-column>
+            <el-table-column prop="allowLogin" label="是否允许登陆">
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.allowLogin ? '' : 'info'"> {{ row.allowLogin }} </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>
@@ -60,116 +60,117 @@
                     <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-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: 'MetaUserList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaUser/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: '/metaUserEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaUserEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaUser/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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(`/metaUser/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+    name: 'MetaUserList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaUser/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: '/metaUserEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaUserEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaUser/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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(`/metaUser/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>

+ 118 - 118
src/main/vue/src/views/MetaUserTaskProgressList.vue

@@ -1,130 +1,130 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<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>
+    <div class="list-view">
+        <page-title>
+            <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="userId" label="用户id"> </el-table-column>
             <el-table-column prop="createdAt" label="操作时间"> </el-table-column>
-			<el-table-column prop="metaTaskToUserId" label="玩家领取任务记录id"> </el-table-column>
-			<el-table-column prop="taskId" label="任务id"> </el-table-column>
-			<el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormatter"> </el-table-column>
-			<el-table-column prop="remark" label="备注"> </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>
+            <el-table-column prop="metaTaskToUserId" label="玩家领取任务记录id"> </el-table-column>
+            <el-table-column prop="taskId" label="任务id"> </el-table-column>
+            <el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormatter"> </el-table-column>
+            <el-table-column prop="remark" label="备注"> </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>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaUserTaskProgressList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaUserTaskProgress/all',
-			downloading: false,
-			taskTypeOptions: [
-				{ label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
-				{ label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
-				{ label: '收集藏品', value: 'COLLECT_COLLECTION' },
-				{ label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
-				{ label: '累计', value: 'ACCUMULATE' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		taskTypeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.taskTypeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaUserTaskProgress/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.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);
-				});
-		}
-	}
+    name: 'MetaUserTaskProgressList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaUserTaskProgress/all',
+            downloading: false,
+            taskTypeOptions: [
+                { label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
+                { label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
+                { label: '收集藏品', value: 'COLLECT_COLLECTION' },
+                { label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
+                { label: '累计', value: 'ACCUMULATE' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        taskTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.taskTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaUserTaskProgress/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .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);
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>

+ 166 - 0
src/main/vue/src/views/MetaVisitorList.vue

@@ -0,0 +1,166 @@
+<template>
+	<div class="list-view">
+		<page-title>
+			<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="avatar" align="center" label="头像">
+				<template slot-scope="{ row }">
+					<el-image
+						style="width: 30px; height: 30px"
+						:src="row.avatar"
+						fit="cover"
+						:preview-src-list="[row.avatar]"
+					>
+					</el-image>
+				</template>
+			</el-table-column>
+			<el-table-column prop="nickname" align="center" label="昵称"> </el-table-column>
+			<el-table-column prop="taboo" align="center" label="是否禁言">
+				<template slot-scope="{ row }">
+					<el-tag :type="row.taboo ? '' : 'info'"> {{ row.taboo }} </el-tag>
+				</template>
+			</el-table-column>
+			<el-table-column label="操作" align="center" fixed="right" width="350">
+				<template slot-scope="{ row }">
+					<el-button @click="cancelTaboo(row)" type="danger" size="mini" plain v-if="row.taboo"> 解除禁言 </el-button>
+					<el-button @click="taboo(row)" type="danger" size="mini" plain v-if="!row.taboo"> 禁言 </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>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+	name: 'MetaVisitorList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			multipleMode: false,
+			search: '',
+			url: '/metaVisitor/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();
+			}
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaVisitor/excel', {
+					responseType: 'blob',
+					params: { size: 10000, query: { del: false } }
+				})
+				.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);
+				});
+		},
+		taboo(row) {
+			this.$alert('确定要将该玩家禁言吗?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaVisitor/taboo/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('禁言成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		},
+		cancelTaboo(row) {
+			this.$alert('确定要解除该玩家禁言吗?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaVisitor/cancelTaboo/${row.id}`);
+				})
+				.then(() => {
+					this.$message.success('解除禁言成功');
+					this.getData();
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$message.error(e.error);
+					}
+				});
+		}
+	}
+};
+</script>
+<style lang="less" scoped>
+
+</style>

+ 144 - 144
src/main/vue/src/views/MetaZombieEdit.vue

@@ -1,26 +1,26 @@
 <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="178px"
-					label-position="right"
-					size="small"
-					style="max-width: 500px"
-				>
-					<el-form-item prop="name" label="配置名称">
-						<el-input v-model="formData.name"> </el-input>
+    <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="178px"
+                    label-position="right"
+                    size="small"
+                    style="max-width: 500px"
+                >
+                    <el-form-item prop="name" label="配置名称">
+                        <el-input v-model="formData.name"> </el-input>
                         <div class="tip">配置名称不可重复</div>
-					</el-form-item>
-					<el-form-item prop="type" label="僵尸类型">
+                    </el-form-item>
+                    <el-form-item prop="type" label="僵尸类型">
                         <el-select v-model="formData.type" clearable filterable placeholder="请选择">
                             <el-option
                                 v-for="item in typeOptions"
@@ -31,134 +31,134 @@
                             </el-option>
                         </el-select>
                     </el-form-item>
-					<el-form-item prop="zombieIntegral" label="僵尸积分">
-						<el-input-number type="number" v-model="formData.zombieIntegral"> </el-input-number>
-					</el-form-item>
-					<el-form-item prop="zombieAttackDamage" label="僵尸攻击伤害">
-						<el-input-number type="number" v-model="formData.zombieAttackDamage"> </el-input-number>
-					</el-form-item>
-					<el-form-item prop="zombieBlood" label="僵尸血量">
-						<el-input-number type="number" v-model="formData.zombieBlood"> </el-input-number>
-					</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>
+                    <el-form-item prop="zombieIntegral" label="僵尸积分">
+                        <el-input-number type="number" v-model="formData.zombieIntegral"> </el-input-number>
+                    </el-form-item>
+                    <el-form-item prop="zombieAttackDamage" label="僵尸攻击伤害">
+                        <el-input-number type="number" v-model="formData.zombieAttackDamage"> </el-input-number>
+                    </el-form-item>
+                    <el-form-item prop="zombieBlood" label="僵尸血量">
+                        <el-input-number type="number" v-model="formData.zombieBlood"> </el-input-number>
+                    </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: 'MetaZombieEdit',
-	created() {
-		if (this.$route.query.id) {
-			this.$http
-				.get('metaZombie/get/' + this.$route.query.id)
-				.then(res => {
-					this.formData = res;
-				})
-				.catch(e => {
-					console.log(e);
-					this.$message.error(e.error);
-				});
-		}
-	},
-	data() {
-		return {
-			typeOptions: [
-				{ label: '普通僵尸', value: 'COMMON' },
+    name: 'MetaZombieEdit',
+    created() {
+        if (this.$route.query.id) {
+            this.$http
+                .get('metaZombie/get/' + this.$route.query.id)
+                .then(res => {
+                    this.formData = res;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.$message.error(e.error);
+                });
+        }
+    },
+    data() {
+        return {
+            typeOptions: [
+                { label: '普通僵尸', value: 'COMMON' },
                 { label: '特殊僵尸', value: 'SPECIAL' }
-			],
-			saving: false,
-			formData: {},
-			rules: {
-				name: [
-					{
-						required: true,
-						message: '请输入配置名称',
-						trigger: 'blur'
-					}
-				],
-				zombieIntegral: [
-					{
-						required: true,
-						message: '请输入僵尸积分',
-						trigger: 'blur'
-					}
-				],
-				zombieAttackDamage: [
-					{
-						required: true,
-						message: '请输入僵尸攻击伤害',
-						trigger: 'blur'
-					}
-				],
-				zombieBlood: [
-					{
-						required: true,
-						message: '请输入僵尸血量',
-						trigger: 'blur'
-					}
-				],
-				type: [
-					{
-						required: true,
-						message: '请选择僵尸类型',
-						trigger: 'blur'
-					}
-				]
-			}
-		};
-	},
-	methods: {
-		onSave() {
-			this.$refs.form.validate(valid => {
-				if (valid) {
-					this.submit();
-				} else {
-					return false;
-				}
-			});
-		},
-		submit() {
-			let data = { ...this.formData };
+            ],
+            saving: false,
+            formData: {},
+            rules: {
+                name: [
+                    {
+                        required: true,
+                        message: '请输入配置名称',
+                        trigger: 'blur'
+                    }
+                ],
+                zombieIntegral: [
+                    {
+                        required: true,
+                        message: '请输入僵尸积分',
+                        trigger: 'blur'
+                    }
+                ],
+                zombieAttackDamage: [
+                    {
+                        required: true,
+                        message: '请输入僵尸攻击伤害',
+                        trigger: 'blur'
+                    }
+                ],
+                zombieBlood: [
+                    {
+                        required: true,
+                        message: '请输入僵尸血量',
+                        trigger: 'blur'
+                    }
+                ],
+                type: [
+                    {
+                        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('/metaZombie/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(`/metaZombie/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('/metaZombie/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(`/metaZombie/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>

+ 185 - 187
src/main/vue/src/views/MetaZombieList.vue

@@ -1,64 +1,63 @@
 <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" align="center" label="ID" width="100"> </el-table-column>
-            <el-table-column prop="name" align="center" label="配置名称" > </el-table-column>
-            <el-table-column prop="type" align="center" label="僵尸类型" :formatter="typeFormatter"> </el-table-column>
-            <el-table-column prop="zombieIntegral" align="center" label="僵尸积分" > </el-table-column>
-            <el-table-column prop="zombieAttackDamage" align="center" label="僵尸攻击伤害" >
-            </el-table-column>
-            <el-table-column prop="zombieBlood" align="center" label="僵尸血量" > </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right">
-                <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">
+	<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="name" align="center" label="配置名称"> </el-table-column>
+			<el-table-column prop="type" align="center" label="僵尸类型" :formatter="typeFormatter"> </el-table-column>
+			<el-table-column prop="zombieIntegral" align="center" label="僵尸积分"> </el-table-column>
+			<el-table-column prop="zombieAttackDamage" align="center" label="僵尸攻击伤害"> </el-table-column>
+			<el-table-column prop="zombieBlood" align="center" label="僵尸血量"> </el-table-column>
+			<el-table-column label="操作" align="center" fixed="right">
+				<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>
@@ -66,147 +65,146 @@
                     <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-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: 'MetaZombieList',
-    mixins: [pageableTable],
-    data() {
-        return {
-            typeOptions: [
+	name: 'MetaZombieList',
+	mixins: [pageableTable],
+	data() {
+		return {
+			typeOptions: [
 				{ label: '普通僵尸', value: 'COMMON' },
-                { label: '特殊僵尸', value: 'SPECIAL' }
+				{ label: '特殊僵尸', value: 'SPECIAL' }
 			],
-            multipleMode: false,
-            search: '',
-            url: '/metaZombie/all',
-            downloading: false
-        };
-    },
-    computed: {
-        selection() {
-            return this.$refs.table.selection.map(i => i.id);
-        }
-    },
-    methods: {
-        typeFormatter(row, column, cellValue, index) {
+			multipleMode: false,
+			search: '',
+			url: '/metaZombie/all',
+			downloading: false
+		};
+	},
+	computed: {
+		selection() {
+			return this.$refs.table.selection.map(i => i.id);
+		}
+	},
+	methods: {
+		typeFormatter(row, column, cellValue, index) {
 			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
 			if (selectedOption) {
 				return selectedOption.label;
 			}
 			return '';
 		},
-        beforeGetData() {
-            return { search: this.search, query: { del: false } };
-        },
-        toggleMultipleMode(multipleMode) {
-            this.multipleMode = multipleMode;
-            if (!multipleMode) {
-                this.$refs.table.clearSelection();
-            }
-        },
-        addRow() {
-            this.$router.push({
-                path: '/metaZombieEdit',
-                query: {
-                    ...this.$route.query
-                }
-            });
-        },
-        editRow(row) {
-            this.$router.push({
-                path: '/metaZombieEdit',
-                query: {
-                    id: row.id
-                }
-            });
-        },
-        download() {
-            this.downloading = true;
-            this.$axios
-                .get('/metaZombie/excel', {
-                    responseType: 'blob',
-                    params: { size: 10000 ,query: { del: false }},
-                })
-                .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.$http
-                .get(`/metaZombie/checkApplication/${row.id}`)
-                .then(() => {
-                    this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
-                        .then(() => {
-                            return this.$http.post(`/metaZombie/del/${row.id}`);
-                        })
-                        .then(() => {
-                            this.$message.success('删除成功');
-                            this.getData();
-                        })
-                        .catch(e => {
-                            if (e !== 'cancel') {
-                                this.$message.error(e.error);
-                            }
-                        });
-                })
-                .catch(e => {
-                    if (e !== 'cancel') {
-                        this.$alert(e.error, '提示', { type: 'info', confirmButtonText: '删除应用数据' })
-                            .then(() => {
-                                return this.$http.post(`/metaGameCopy/${row.id}/delMetaZombieId`);
-                            })
-                            .then(() => {
-                                this.$message.success('删除应用数据成功,当前您可以删除该配置');
-                                
-                            })
-                            .catch(e => {
-                                if (e !== 'cancel') {
-                                    this.$message.error(e.error);
-                                }
-                            });
-                    }
-                });
-        }
-    }
+		beforeGetData() {
+			return { search: this.search, query: { del: false } };
+		},
+		toggleMultipleMode(multipleMode) {
+			this.multipleMode = multipleMode;
+			if (!multipleMode) {
+				this.$refs.table.clearSelection();
+			}
+		},
+		addRow() {
+			this.$router.push({
+				path: '/metaZombieEdit',
+				query: {
+					...this.$route.query
+				}
+			});
+		},
+		editRow(row) {
+			this.$router.push({
+				path: '/metaZombieEdit',
+				query: {
+					id: row.id
+				}
+			});
+		},
+		download() {
+			this.downloading = true;
+			this.$axios
+				.get('/metaZombie/excel', {
+					responseType: 'blob',
+					params: { size: 10000, query: { del: false } }
+				})
+				.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.$http
+				.get(`/metaZombie/checkApplication/${row.id}`)
+				.then(() => {
+					this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+						.then(() => {
+							return this.$http.post(`/metaZombie/del/${row.id}`);
+						})
+						.then(() => {
+							this.$message.success('删除成功');
+							this.getData();
+						})
+						.catch(e => {
+							if (e !== 'cancel') {
+								this.$message.error(e.error);
+							}
+						});
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						this.$alert(e.error, '提示', { type: 'info', confirmButtonText: '删除应用数据' })
+							.then(() => {
+								return this.$http.post(`/metaGameCopy/${row.id}/delMetaZombieId`);
+							})
+							.then(() => {
+								this.$message.success('删除应用数据成功,当前您可以删除该配置');
+							})
+							.catch(e => {
+								if (e !== 'cancel') {
+									this.$message.error(e.error);
+								}
+							});
+					}
+				});
+		}
+	}
 };
 </script>
 <style lang="less" scoped>

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

@@ -95,7 +95,7 @@ export default {
 	},
 	methods: {
 		beforeGetData() {
-			return { search: this.search, query: { del: false } };
+			return { search: this.search, query: { del: false, type: 1 } };
 		},
 		toggleMultipleMode(multipleMode) {
 			this.multipleMode = multipleMode;