xiongzhu il y a 4 ans
Parent
commit
fb96390375
23 fichiers modifiés avec 563 ajouts et 47 suppressions
  1. 2 0
      src/main/java/com/izouma/nineth/converter/FileObjectConverter.java
  2. 2 0
      src/main/java/com/izouma/nineth/converter/FileObjectListConverter.java
  3. 2 0
      src/main/java/com/izouma/nineth/converter/JSONObjectConverter.java
  4. 2 0
      src/main/java/com/izouma/nineth/converter/LongArrayConverter.java
  5. 34 0
      src/main/java/com/izouma/nineth/converter/PrivilegeListConverter.java
  6. 34 0
      src/main/java/com/izouma/nineth/converter/PropertyListConverter.java
  7. 2 0
      src/main/java/com/izouma/nineth/converter/StringArrayConverter.java
  8. 3 3
      src/main/java/com/izouma/nineth/domain/Asset.java
  9. 3 3
      src/main/java/com/izouma/nineth/domain/BlindBoxItem.java
  10. 3 3
      src/main/java/com/izouma/nineth/domain/BlinkBox.java
  11. 7 33
      src/main/java/com/izouma/nineth/domain/Collection.java
  12. 11 0
      src/main/java/com/izouma/nineth/domain/CollectionProperty.java
  13. 3 3
      src/main/java/com/izouma/nineth/domain/Order.java
  14. 18 0
      src/main/java/com/izouma/nineth/domain/Privilege.java
  15. 20 0
      src/main/java/com/izouma/nineth/domain/PrivilegeOption.java
  16. 16 0
      src/main/java/com/izouma/nineth/repo/PrivilegeOptionRepo.java
  17. 20 0
      src/main/java/com/izouma/nineth/service/PrivilegeOptionService.java
  18. 60 0
      src/main/java/com/izouma/nineth/web/PrivilegeOptionController.java
  19. 2 1
      src/main/resources/application.yaml
  20. 1 0
      src/main/resources/genjson/PrivilegeOption.json
  21. 17 1
      src/main/vue/src/router.js
  22. 127 0
      src/main/vue/src/views/PrivilegeOptionEdit.vue
  23. 174 0
      src/main/vue/src/views/PrivilegeOptionList.vue

+ 2 - 0
src/main/java/com/izouma/nineth/converter/FileObjectConverter.java

@@ -5,7 +5,9 @@ import com.izouma.nineth.domain.FileObject;
 import org.apache.commons.lang3.StringUtils;
 
 import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
 
+@Converter
 public class FileObjectConverter implements AttributeConverter<FileObject, String> {
     @Override
     public String convertToDatabaseColumn(FileObject fileObject) {

+ 2 - 0
src/main/java/com/izouma/nineth/converter/FileObjectListConverter.java

@@ -5,11 +5,13 @@ import com.izouma.nineth.domain.FileObject;
 import org.apache.commons.lang3.StringUtils;
 
 import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
 import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+@Converter
 public class FileObjectListConverter implements AttributeConverter<List<FileObject>, String> {
     @Override
     public String convertToDatabaseColumn(List<FileObject> list) {

+ 2 - 0
src/main/java/com/izouma/nineth/converter/JSONObjectConverter.java

@@ -5,8 +5,10 @@ import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
 
 @Slf4j
+@Converter
 public class JSONObjectConverter implements AttributeConverter<JSONObject, String> {
     @Override
     public String convertToDatabaseColumn(JSONObject jsonObject) {

+ 2 - 0
src/main/java/com/izouma/nineth/converter/LongArrayConverter.java

@@ -3,11 +3,13 @@ package com.izouma.nineth.converter;
 import org.apache.commons.lang3.StringUtils;
 
 import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 
+@Converter
 public class LongArrayConverter implements AttributeConverter<List<Long>, String> {
     @Override
     public String convertToDatabaseColumn(List<Long> longs) {

+ 34 - 0
src/main/java/com/izouma/nineth/converter/PrivilegeListConverter.java

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

+ 34 - 0
src/main/java/com/izouma/nineth/converter/PropertyListConverter.java

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

+ 2 - 0
src/main/java/com/izouma/nineth/converter/StringArrayConverter.java

@@ -3,10 +3,12 @@ package com.izouma.nineth.converter;
 import org.apache.commons.lang3.StringUtils;
 
 import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+@Converter
 public class StringArrayConverter implements AttributeConverter<List<String>, String> {
     @Override
     public String convertToDatabaseColumn(List<String> strings) {

+ 3 - 3
src/main/java/com/izouma/nineth/domain/Asset.java

@@ -2,7 +2,7 @@ package com.izouma.nineth.domain;
 
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.converter.FileObjectListConverter;
-import com.izouma.nineth.converter.StringArrayConverter;
+import com.izouma.nineth.converter.PropertyListConverter;
 import com.izouma.nineth.enums.AssetStatus;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -49,9 +49,9 @@ public class Asset extends BaseEntity {
     private String detail;
 
     @Column(columnDefinition = "TEXT")
-    @Convert(converter = Collection.PropertyListConverter.class)
+    @Convert(converter = PropertyListConverter.class)
     @ApiModelProperty("特性")
-    private List<Collection.CollectionProperty> properties;
+    private List<CollectionProperty> properties;
 
     @ApiModelProperty("分类")
     private String category;

+ 3 - 3
src/main/java/com/izouma/nineth/domain/BlindBoxItem.java

@@ -2,7 +2,7 @@ package com.izouma.nineth.domain;
 
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.converter.FileObjectListConverter;
-import com.izouma.nineth.converter.StringArrayConverter;
+import com.izouma.nineth.converter.PropertyListConverter;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -63,9 +63,9 @@ public class BlindBoxItem extends BaseEntity {
     private BigDecimal price;
 
     @Column(columnDefinition = "TEXT")
-    @Convert(converter = Collection.PropertyListConverter.class)
+    @Convert(converter = PropertyListConverter.class)
     @ApiModelProperty("特性")
-    private List<Collection.CollectionProperty> properties;
+    private List<CollectionProperty> properties;
 
     @ApiModelProperty("是否可转售")
     private boolean canResale;

+ 3 - 3
src/main/java/com/izouma/nineth/domain/BlinkBox.java

@@ -2,7 +2,7 @@ package com.izouma.nineth.domain;
 
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.converter.FileObjectListConverter;
-import com.izouma.nineth.converter.StringArrayConverter;
+import com.izouma.nineth.converter.PropertyListConverter;
 import com.izouma.nineth.enums.CollectionSource;
 import com.izouma.nineth.enums.CollectionType;
 import io.swagger.annotations.ApiModel;
@@ -75,7 +75,7 @@ public class BlinkBox extends BaseEntity {
     private BigDecimal price;
 
     @Column(columnDefinition = "TEXT")
-    @Convert(converter = Collection.PropertyListConverter.class)
+    @Convert(converter = PropertyListConverter.class)
     @ApiModelProperty("特性")
-    private List<Collection.CollectionProperty> properties;
+    private List<CollectionProperty> properties;
 }

+ 7 - 33
src/main/java/com/izouma/nineth/domain/Collection.java

@@ -1,10 +1,9 @@
 package com.izouma.nineth.domain;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.converter.FileObjectListConverter;
-import com.izouma.nineth.converter.StringArrayConverter;
+import com.izouma.nineth.converter.PrivilegeListConverter;
+import com.izouma.nineth.converter.PropertyListConverter;
 import com.izouma.nineth.enums.CollectionSource;
 import com.izouma.nineth.enums.CollectionType;
 import io.swagger.annotations.ApiModel;
@@ -13,7 +12,6 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import org.apache.commons.lang3.StringUtils;
 
 import javax.persistence.*;
 import java.math.BigDecimal;
@@ -71,6 +69,11 @@ public class Collection extends BaseEntity {
     @ApiModelProperty("特性")
     private List<CollectionProperty> properties;
 
+    @Column(columnDefinition = "TEXT")
+    @Convert(converter = PrivilegeListConverter.class)
+    @ApiModelProperty("特权")
+    private List<Privilege> privileges;
+
     @ApiModelProperty("是否可转售")
     private boolean canResale;
 
@@ -116,33 +119,4 @@ public class Collection extends BaseEntity {
 
     private int sort;
 
-    @Data
-    public static class CollectionProperty {
-
-        private String name;
-
-        private String value;
-    }
-
-    public static class PropertyListConverter implements AttributeConverter<List<CollectionProperty>, String> {
-        @Override
-        public String convertToDatabaseColumn(List<CollectionProperty> collectionProperties) {
-            if (collectionProperties == null) {
-                return null;
-            }
-            return JSON.toJSONString(collectionProperties);
-        }
-
-        @Override
-        public List<CollectionProperty> convertToEntityAttribute(String s) {
-            if (StringUtils.isEmpty(s)) {
-                return null;
-            }
-            try {
-                return JSONArray.parseArray(s, CollectionProperty.class);
-            } catch (Exception ignored) {
-            }
-            return null;
-        }
-    }
 }

+ 11 - 0
src/main/java/com/izouma/nineth/domain/CollectionProperty.java

@@ -0,0 +1,11 @@
+package com.izouma.nineth.domain;
+
+import lombok.Data;
+
+@Data
+public class CollectionProperty {
+
+    private String name;
+
+    private String value;
+}

+ 3 - 3
src/main/java/com/izouma/nineth/domain/Order.java

@@ -2,7 +2,7 @@ package com.izouma.nineth.domain;
 
 import com.izouma.nineth.annotations.Searchable;
 import com.izouma.nineth.converter.FileObjectListConverter;
-import com.izouma.nineth.converter.StringArrayConverter;
+import com.izouma.nineth.converter.PropertyListConverter;
 import com.izouma.nineth.enums.CollectionType;
 import com.izouma.nineth.enums.OrderStatus;
 import com.izouma.nineth.enums.PayMethod;
@@ -53,9 +53,9 @@ public class Order extends BaseEntity {
     private String detail;
 
     @Column(columnDefinition = "TEXT")
-    @Convert(converter = Collection.PropertyListConverter.class)
+    @Convert(converter = PropertyListConverter.class)
     @ApiModelProperty("特性")
-    private List<Collection.CollectionProperty> properties;
+    private List<CollectionProperty> properties;
 
     @ApiModelProperty("分类")
     private String category;

+ 18 - 0
src/main/java/com/izouma/nineth/domain/Privilege.java

@@ -0,0 +1,18 @@
+package com.izouma.nineth.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Privilege extends PrivilegeOption {
+
+    private boolean opened;
+
+    private LocalDateTime openTime;
+
+}

+ 20 - 0
src/main/java/com/izouma/nineth/domain/PrivilegeOption.java

@@ -0,0 +1,20 @@
+package com.izouma.nineth.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+
+@Data
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+public class PrivilegeOption extends BaseEntity {
+
+    private String name;
+
+    private String description;
+
+    private String icon;
+}

+ 16 - 0
src/main/java/com/izouma/nineth/repo/PrivilegeOptionRepo.java

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

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

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

+ 60 - 0
src/main/java/com/izouma/nineth/web/PrivilegeOptionController.java

@@ -0,0 +1,60 @@
+package com.izouma.nineth.web;
+import com.izouma.nineth.domain.PrivilegeOption;
+import com.izouma.nineth.service.PrivilegeOptionService;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.PrivilegeOptionRepo;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/privilegeOption")
+@AllArgsConstructor
+public class PrivilegeOptionController extends BaseController {
+    private PrivilegeOptionService privilegeOptionService;
+    private PrivilegeOptionRepo privilegeOptionRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public PrivilegeOption save(@RequestBody PrivilegeOption record) {
+        if (record.getId() != null) {
+            PrivilegeOption orig = privilegeOptionRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return privilegeOptionRepo.save(orig);
+        }
+        return privilegeOptionRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<PrivilegeOption> all(@RequestBody PageQuery pageQuery) {
+        return privilegeOptionService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public PrivilegeOption get(@PathVariable Long id) {
+        return privilegeOptionRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        privilegeOptionRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<PrivilegeOption> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

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

@@ -130,9 +130,10 @@ spring:
 spring:
   profiles: prod
   datasource:
-    url: jdbc:mysql://rm-wz9y2p75f51a2o19k.mysql.rds.aliyuncs.com:53306/9th_test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
+    url: jdbc:mysql://rm-wz9y2p75f51a2o19k.mysql.rds.aliyuncs.com:53306/9th?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
   redis:
     host: 127.0.0.1
+    database: 1
 general:
   host: https://nft.9space.vip
 wx:

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

@@ -0,0 +1 @@
+{"tableName":"PrivilegeOption","className":"PrivilegeOption","remark":"特权配置","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/drew/Projects/Java/9th/src/main/java/com/izouma/nineth","viewPath":"/Users/drew/Projects/Java/9th/src/main/vue/src/views","routerPath":"/Users/drew/Projects/Java/9th/src/main/vue/src","resourcesPath":"/Users/drew/Projects/Java/9th/src/main/resources","dataBaseType":"Mysql","fields":[{"name":"name","modelName":"name","remark":"名称","showInList":true,"showInForm":true,"formType":"singleLineText","required":true},{"name":"description","modelName":"description","remark":"描述","showInList":true,"showInForm":true,"formType":"singleLineText","required":true},{"name":"icon","modelName":"icon","remark":"图标","showInList":true,"showInForm":true,"formType":"singleImage","required":true}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.nineth","tablePackage":"com.izouma.nineth.domain.PrivilegeOption"}

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

@@ -299,6 +299,22 @@ const router = new Router({
                         title: '账号管理'
                     }
                 },
+                {
+                    path: '/privilegeOptionEdit',
+                    name: 'PrivilegeOptionEdit',
+                    component: () => import(/* webpackChunkName: "privilegeOptionEdit" */ '@/views/PrivilegeOptionEdit.vue'),
+                    meta: {
+                       title: '特权配置编辑',
+                    },
+                },
+                {
+                    path: '/privilegeOptionList',
+                    name: 'PrivilegeOptionList',
+                    component: () => import(/* webpackChunkName: "privilegeOptionList" */ '@/views/PrivilegeOptionList.vue'),
+                    meta: {
+                       title: '特权配置',
+                    },
+               }
                 /**INSERT_LOCATION**/
             ]
         },
@@ -350,4 +366,4 @@ router.beforeEach((to, from, next) => {
     }
 });
 
-export default router;
+export default router;

+ 127 - 0
src/main/vue/src/views/PrivilegeOptionEdit.vue

@@ -0,0 +1,127 @@
+<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="52px" label-position="right"
+                         size="small"
+                         style="max-width: 500px;">
+                        <el-form-item prop="name" label="名称">
+                                    <el-input v-model="formData.name"></el-input>
+                        </el-form-item>
+                        <el-form-item prop="description" label="描述">
+                                    <el-input v-model="formData.description"></el-input>
+                        </el-form-item>
+                        <el-form-item prop="icon" label="图标">
+                                    <single-upload v-model="formData.icon"></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: 'PrivilegeOptionEdit',
+        created() {
+            if (this.$route.query.id) {
+                this.$http
+                    .get('privilegeOption/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'
+                        },
+                    ],
+                    description: [
+                        {
+                            required: true,
+                            message: '请输入描述',
+                            trigger: 'blur'
+                        },
+                    ],
+                    icon: [
+                        {
+                            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('/privilegeOption/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(`/privilegeOption/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>

+ 174 - 0
src/main/vue/src/views/PrivilegeOptionList.vue

@@ -0,0 +1,174 @@
+<template>
+    <div  class="list-view">
+        <page-title>
+            <el-button @click="addRow" type="primary" icon="el-icon-plus" :disabled="fetchingData || downloading" class="filter-item">
+                新增
+            </el-button>
+            <el-button @click="download" icon="el-icon-upload2" :loading="downloading" :disabled="fetchingData" class="filter-item">
+                导出
+            </el-button>
+        </page-title>
+        <div class="filters-container">
+            <el-input
+                    placeholder="搜索..."
+                    v-model="search"
+                    clearable
+                    class="filter-item search"
+                    @keyup.enter.native="getData"
+            >
+                <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
+            </el-input>
+        </div>
+        <el-table :data="tableData" row-key="id" ref="table"
+                  header-row-class-name="table-header-row"
+                  header-cell-class-name="table-header-cell"
+                  row-class-name="table-row" cell-class-name="table-cell"
+                  :height="tableHeight" v-loading="fetchingData">
+            <el-table-column v-if="multipleMode" align="center" type="selection"
+                             width="50">
+            </el-table-column>
+            <el-table-column prop="id" label="ID" width="100">
+            </el-table-column>
+                                <el-table-column prop="name" label="名称"
+>
+                    </el-table-column>
+                    <el-table-column prop="description" label="描述"
+>
+                    </el-table-column>
+                    <el-table-column prop="icon" label="图标"
+>
+                            <template slot-scope="{row}">
+                                <el-image style="width: 30px; height: 30px"
+                                          :src="row.icon" fit="cover"
+                                          :preview-src-list="[row.icon]"></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>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination background @size-change="onSizeChange"
+                           @current-change="onCurrentChange" :current-page="page"
+                           :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
+                           layout="total, sizes, prev, pager, next, jumper"
+                           :total="totalElements">
+            </el-pagination>
+        </div>
+
+    </div>
+</template>
+<script>
+    import { mapState } from "vuex";
+    import pageableTable from "@/mixins/pageableTable";
+
+    export default {
+        name: 'PrivilegeOptionList',
+        mixins: [pageableTable],
+        data() {
+            return {
+                multipleMode: false,
+                search: "",
+                url: "/privilegeOption/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: "/privilegeOptionEdit",
+                    query: {
+                        ...this.$route.query
+                    }
+                });
+            },
+            editRow(row) {
+                this.$router.push({
+                    path: "/privilegeOptionEdit",
+                    query: {
+                    id: row.id
+                    }
+                });
+            },
+            download() {
+                this.downloading = true;
+                this.$axios
+                    .get("/privilegeOption/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(`/privilegeOption/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>