xiongzhu 3 лет назад
Родитель
Сommit
c2d6deaf81
26 измененных файлов с 696 добавлено и 388 удалено
  1. 3 0
      src/main/java/com/izouma/nineth/domain/Banner.java
  2. 0 3
      src/main/java/com/izouma/nineth/domain/Company.java
  3. 3 0
      src/main/java/com/izouma/nineth/domain/News.java
  4. 4 0
      src/main/java/com/izouma/nineth/domain/Recommend.java
  5. 3 0
      src/main/java/com/izouma/nineth/domain/User.java
  6. 2 1
      src/main/java/com/izouma/nineth/enums/AuthorityName.java
  7. 2 2
      src/main/java/com/izouma/nineth/repo/CollectionRepo.java
  8. 16 0
      src/main/java/com/izouma/nineth/repo/CompanyRepo.java
  9. 2 2
      src/main/java/com/izouma/nineth/repo/NewsRepo.java
  10. 4 0
      src/main/java/com/izouma/nineth/service/CacheService.java
  11. 2 2
      src/main/java/com/izouma/nineth/service/CollectionService.java
  12. 58 0
      src/main/java/com/izouma/nineth/service/CompanyService.java
  13. 1 0
      src/main/java/com/izouma/nineth/service/UserService.java
  14. 12 0
      src/main/java/com/izouma/nineth/web/AuthorityController.java
  15. 1 0
      src/main/java/com/izouma/nineth/web/BannerController.java
  16. 4 24
      src/main/java/com/izouma/nineth/web/CollectionController.java
  17. 73 0
      src/main/java/com/izouma/nineth/web/CompanyController.java
  18. 2 0
      src/main/java/com/izouma/nineth/web/UserController.java
  19. 1 0
      src/main/resources/genjson/Company.json
  20. 1 0
      src/main/vue/src/mixins/pageableTable.js
  21. 105 73
      src/main/vue/src/router.js
  22. 1 1
      src/main/vue/src/views/AdminEdit.vue
  23. 258 0
      src/main/vue/src/views/CompanyAdmin.vue
  24. 61 156
      src/main/vue/src/views/CompanyEdit.vue
  25. 74 122
      src/main/vue/src/views/CompanyList.vue
  26. 3 2
      src/main/vue/src/views/Menus.vue

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

@@ -51,4 +51,7 @@ public class Banner extends BaseEntity {
 
     @ApiModelProperty("背景颜色")
     private String backgroundColor;
+
+    @Column(columnDefinition = "bigint default 1 not null")
+    private Long companyId = 1L;
 }

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

@@ -20,8 +20,5 @@ public class Company extends BaseEntity {
 
     private String logo;
 
-    private Long adminUserId;
-
     private boolean disabled;
-
 }

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

@@ -45,4 +45,7 @@ public class News extends BaseEntity {
 
     @ApiModelProperty("跳转内容")
     private String linkContent;
+
+    @Column(columnDefinition = "bigint default 1 not null")
+    private Long companyId = 1L;
 }

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

@@ -6,6 +6,7 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Index;
 import javax.persistence.Table;
@@ -35,4 +36,7 @@ public class Recommend extends BaseEntity {
     /*藏品,新闻*/
     @ApiModelProperty("种类")
     private String category;
+
+    @Column(columnDefinition = "bigint default 1 not null")
+    private Long companyId = 1L;
 }

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

@@ -78,6 +78,7 @@ public class User extends UserBaseEntity implements Serializable {
     @BatchSize(size = 20)
     @ExcelIgnore
     @JsonSerialize(using = UserAuthoritySerializer.class, as = HashSet.class)
+    @JsonView(View.Detail.class)
     private Set<Authority> authorities = new HashSet<>();
 
     private String openId;
@@ -191,4 +192,6 @@ public class User extends UserBaseEntity implements Serializable {
     @Column(columnDefinition = "tinyint unsigned default 1")
     @ApiModelProperty("主页是否展示")
     private Boolean isPublicShow = Boolean.TRUE;
+
+    private Long companyId;
 }

+ 2 - 1
src/main/java/com/izouma/nineth/enums/AuthorityName.java

@@ -9,7 +9,8 @@ public enum AuthorityName {
     ROLE_NEWS("新闻管理员"),
     ROLE_ORDERINFO("订单查看"),
     ROLE_COMPANY("企业用户"),
-    ROLE_MESSAGE("留言管理员")
+    ROLE_MESSAGE("留言管理员"),
+    ROLE_SAAS("SAAS管理员")
     ;
     private final String description;
 

+ 2 - 2
src/main/java/com/izouma/nineth/repo/CollectionRepo.java

@@ -77,8 +77,8 @@ public interface CollectionRepo extends JpaRepository<Collection, Long>, JpaSpec
     Collection save(@Nonnull Collection collection);
 
     @Query("select new com.izouma.nineth.dto.RecommendCollection(c,r) from Collection c join Recommend r on c.id = r.collectionId " +
-            "where c.del = false and c.onShelf = true and r.type = ?1 and r.category = 'COLLECTION' order by r.sort desc")
-    List<RecommendCollection> recommend(String type);
+            "where c.del = false and c.onShelf = true and r.companyId = ?2 and r.type = ?1 and r.category = 'COLLECTION' order by r.sort desc")
+    List<RecommendCollection> recommend(String type, Long companyId);
 
     @Transactional
     @Modifying

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

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

+ 2 - 2
src/main/java/com/izouma/nineth/repo/NewsRepo.java

@@ -25,7 +25,7 @@ public interface NewsRepo extends JpaRepository<News, Long>, JpaSpecificationExe
     void addLike(Long id, int num);
 
     @Query("select new com.izouma.nineth.dto.RecommendNews(n,r) from News n join Recommend r on n.id = r.collectionId " +
-                "where n.del = false and r.type = ?1 and r.category = 'NEWS' order by r.sort desc")
-    List<RecommendNews> recommend(String type);
+                "where n.del = false and r.companyId = ?2 and r.type = ?1 and r.category = 'NEWS' order by r.sort desc")
+    List<RecommendNews> recommend(String type, Long companyId);
 
 }

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

@@ -131,4 +131,8 @@ public class CacheService {
     public void clearAuction(Long id) {
     }
 
+    @CacheEvict(value = "userList", allEntries = true)
+    public void clearUserList() {
+    }
+
 }

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

@@ -633,8 +633,8 @@ public class CollectionService {
     }
 
     @Cacheable(value = "recommendLegacy", key = "#type")
-    public List<CollectionDTO> recommendLegacy(@RequestParam String type) {
-        return collectionRepo.recommend(type).stream().map(rc -> {
+    public List<CollectionDTO> recommendLegacy(@RequestParam String type, Long companyId) {
+        return collectionRepo.recommend(type, companyId).stream().map(rc -> {
             if (StringUtils.isNotBlank(rc.getRecommend().getPic())) {
                 rc.getCollection().setPic(Collections.singletonList(new FileObject(null, rc.getRecommend()
                         .getPic(), null, null)));

+ 58 - 0
src/main/java/com/izouma/nineth/service/CompanyService.java

@@ -0,0 +1,58 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.config.Constants;
+import com.izouma.nineth.domain.Company;
+import com.izouma.nineth.domain.User;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.AuthorityName;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.CompanyRepo;
+import com.izouma.nineth.repo.UserRepo;
+import com.izouma.nineth.security.Authority;
+import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.utils.SecurityUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+
+@Service
+@AllArgsConstructor
+public class CompanyService {
+
+    private CompanyRepo     companyRepo;
+    private UserRepo        userRepo;
+    private PasswordEncoder passwordEncoder;
+    private CacheService    cacheService;
+
+    public Page<Company> all(PageQuery pageQuery) {
+        return companyRepo.findAll(JpaUtils.toSpecification(pageQuery, Company.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    public void addAdmin(Long companyId, String username, String password) {
+        if (!SecurityUtils.hasRole(AuthorityName.ROLE_ADMIN)
+                && !companyId.equals(SecurityUtils.getAuthenticatedUser().getCompanyId())) {
+            throw new BusinessException("无权限");
+        }
+        userRepo.save(User.builder()
+                .avatar(Constants.DEFAULT_AVATAR)
+                .username(username)
+                .password(passwordEncoder.encode(password))
+                .companyId(companyId)
+                .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_SAAS)))
+                .admin(true)
+                .build());
+        cacheService.clearUserList();
+    }
+
+    public void delAdmin(Long companyId, Long userId) {
+        if (!SecurityUtils.hasRole(AuthorityName.ROLE_ADMIN)
+                && !companyId.equals(SecurityUtils.getAuthenticatedUser().getCompanyId())) {
+            throw new BusinessException("无权限");
+        }
+        userRepo.deleteById(userId);
+        cacheService.clearUserList();
+    }
+}

+ 1 - 0
src/main/java/com/izouma/nineth/service/UserService.java

@@ -140,6 +140,7 @@ public class UserService {
             cacheService.clearUserMy(user.getId());
             cacheService.clearUser(user.getId());
         }
+        cacheService.clearUserList();
         return userRepo.save(user);
     }
 

+ 12 - 0
src/main/java/com/izouma/nineth/web/AuthorityController.java

@@ -1,11 +1,13 @@
 package com.izouma.nineth.web;
 
+import com.izouma.nineth.enums.AuthorityName;
 import com.izouma.nineth.repo.AuthorityRepo;
 import com.izouma.nineth.security.Authority;
 import lombok.AllArgsConstructor;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.PostConstruct;
 import java.util.List;
 
 @RestController
@@ -25,4 +27,14 @@ public class AuthorityController extends BaseController {
     public Authority save(Authority authority) {
         return authorityRepo.save(authority);
     }
+
+    @PostConstruct
+    public void init() {
+        List<Authority> list = authorityRepo.findAll();
+        for (AuthorityName value : AuthorityName.values()) {
+            if (list.stream().noneMatch(a -> a.getName().equals(value.name()))) {
+                authorityRepo.save(new Authority(value.name(), value.getDescription()));
+            }
+        }
+    }
 }

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

@@ -45,6 +45,7 @@ public class BannerController extends BaseController {
     @PostMapping("/all")
     public Page<Banner> all(@RequestBody PageQuery pageQuery) {
         pageQuery.getQuery().put("del", false);
+        pageQuery.getQuery().putIfAbsent("companyId", 1);
         return bannerService.all(pageQuery).toPage();
     }
 

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

@@ -139,36 +139,16 @@ public class CollectionController extends BaseController {
         collectionService.appointment(id, SecurityUtils.getAuthenticatedUser().getId());
     }
 
-    //    @GetMapping("/recommend")
-//    @Cacheable("recommend")
-    public List<CollectionDTO> recommend(@RequestParam String type) {
-        return collectionRepo.recommend(type).stream().map(rc -> {
-            if (StringUtils.isNotBlank(rc.getRecommend().getPic())) {
-                rc.getCollection().setPic(Collections.singletonList(new FileObject(null, rc.getRecommend()
-                        .getPic(), null, null)));
-            }
-            CollectionDTO collectionDTO = new CollectionDTO();
-            BeanUtils.copyProperties(rc.getCollection(), collectionDTO);
-
-            // 减少数据量
-            collectionDTO.setDetail(null);
-            collectionDTO.setPrivileges(null);
-            collectionDTO.setProperties(null);
-
-            return collectionDTO;
-        }).collect(Collectors.toList());
-    }
-
     @GetMapping("/recommend")
     @Cacheable("recommend")
-    public Object recommendAll(@RequestParam(required = false) String type) {
+    public Object recommendAll(@RequestParam(required = false) String type, @RequestParam(defaultValue = "1") Long companyId) {
         if (StringUtils.isNotEmpty(type)) {
-            return collectionService.recommendLegacy(type);
+            return collectionService.recommendLegacy(type, companyId);
         }
 
         List<RecommendDTO> recommedDTOS = new ArrayList<>();
 
-        List<RecommendDTO> collectionDTOS = collectionRepo.recommend("LIST").stream().map(rc -> {
+        List<RecommendDTO> collectionDTOS = collectionRepo.recommend("LIST", companyId).stream().map(rc -> {
             if (StringUtils.isNotBlank(rc.getRecommend().getPic())) {
                 rc.getCollection().setPic(Collections.singletonList(new FileObject(null, rc.getRecommend()
                         .getPic(), null, null)));
@@ -185,7 +165,7 @@ public class CollectionController extends BaseController {
                     .getCreatedAt());
         }).collect(Collectors.toList());
 
-        List<RecommendDTO> news = newsRepo.recommend("LIST").stream().map(rn -> {
+        List<RecommendDTO> news = newsRepo.recommend("LIST", companyId).stream().map(rn -> {
             if (StringUtils.isNotBlank(rn.getRecommend().getPic())) {
                 rn.getNews().setPic(rn.getRecommend().getPic());
             }

+ 73 - 0
src/main/java/com/izouma/nineth/web/CompanyController.java

@@ -0,0 +1,73 @@
+package com.izouma.nineth.web;
+
+import com.izouma.nineth.domain.Company;
+import com.izouma.nineth.service.CompanyService;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.CompanyRepo;
+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("/company")
+@AllArgsConstructor
+public class CompanyController extends BaseController {
+    private CompanyService companyService;
+    private CompanyRepo    companyRepo;
+
+    @PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public Company save(@RequestBody Company record) {
+        if (record.getId() != null) {
+            Company orig = companyRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return companyRepo.save(orig);
+        }
+        return companyRepo.save(record);
+    }
+
+
+    @PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/all")
+    public Page<Company> all(@RequestBody PageQuery pageQuery) {
+        return companyService.all(pageQuery);
+    }
+
+    @GetMapping("/get/{id}")
+    public Company get(@PathVariable Long id) {
+        return companyRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        companyRepo.softDelete(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<Company> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+
+    @PreAuthorize("hasAnyRole('ADMIN', 'SAAS')")
+    @PostMapping("/addAdmin")
+    public void addAdmin(@RequestParam Long companyId, @RequestParam String username, @RequestParam String password) {
+        companyService.addAdmin(companyId, username, password);
+    }
+
+    @PreAuthorize("hasAnyRole('ADMIN', 'SAAS')")
+    @PostMapping("/delAdmin")
+    public void delAdmin(@RequestParam Long companyId, @RequestParam Long userId) {
+        companyService.delAdmin(companyId, userId);
+    }
+}
+

+ 2 - 0
src/main/java/com/izouma/nineth/web/UserController.java

@@ -1,6 +1,7 @@
 package com.izouma.nineth.web;
 
 import com.alipay.api.AlipayApiException;
+import com.fasterxml.jackson.annotation.JsonView;
 import com.huifu.adapay.core.exception.BaseAdaPayException;
 import com.izouma.nineth.converter.EncryptConverter;
 import com.izouma.nineth.domain.IdentityAuth;
@@ -137,6 +138,7 @@ public class UserController extends BaseController {
 
     @PreAuthorize("hasRole('ADMIN')")
     @GetMapping("/adminGet/{id}")
+    @JsonView(User.View.Detail.class)
     public User adminGet(@PathVariable Long id) {
         return userRepo.findById(id).orElseThrow(new BusinessException("无记录"));
     }

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

@@ -0,0 +1 @@
+{"tableName":"Company","className":"Company","remark":"企业管理","genTable":true,"genClass":true,"genList":true,"genForm":true,"genRouter":true,"javaPath":"/Users/drew/Projects/Java/raex_back/src/main/java/com/izouma/nineth","viewPath":"/Users/drew/Projects/Java/raex_back/src/main/vue/src/views","routerPath":"/Users/drew/Projects/Java/raex_back/src/main/vue/src","resourcesPath":"/Users/drew/Projects/Java/raex_back/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":"textarea"},{"name":"logo","modelName":"logo","remark":"LOGO","showInList":true,"showInForm":true,"formType":"singleImage","required":true},{"name":"adminUserId","modelName":"adminUserId","remark":"管理员","showInList":true,"showInForm":true,"formType":"number","required":true},{"name":"disabled","modelName":"disabled","remark":"禁用","showInList":true,"showInForm":true,"formType":"switch","required":true}],"readTable":false,"dataSourceCode":"dataSource","genJson":"","subtables":[],"update":false,"basePackage":"com.izouma.nineth","tablePackage":"com.izouma.nineth.domain.Company"}

+ 1 - 0
src/main/vue/src/mixins/pageableTable.js

@@ -13,6 +13,7 @@ export default {
         };
     },
     created() {
+        this.beforeCreated && this.beforeCreated();
         this.page = Number(this.$route.query.page) || 1;
         if (this.$route.query.sort) {
             let sort = {};

+ 105 - 73
src/main/vue/src/router.js

@@ -621,7 +621,7 @@ const router = new Router({
                     component: () =>
                         import(
                             /* webpackChunkName: "collectionPendingList" */ '@/views/company/CollectionPendingList.vue'
-                            ),
+                        ),
                     meta: {
                         title: '申请中藏品'
                     }
@@ -650,7 +650,7 @@ const router = new Router({
                     component: () =>
                         import(
                             /* webpackChunkName: "companyCollectionEdit" */ '@/views/company/CompanyCollectionEdit.vue'
-                            ),
+                        ),
                     meta: {
                         title: '企业藏品编辑'
                     }
@@ -661,7 +661,7 @@ const router = new Router({
                     component: () =>
                         import(
                             /* webpackChunkName: "companyCollectionShelf" */ '@/views/company/CompanyCollectionShelf.vue'
-                            ),
+                        ),
                     meta: {
                         title: '企业藏品查看'
                     }
@@ -727,7 +727,8 @@ const router = new Router({
                 {
                     path: '/auctionOrderUsedList',
                     name: 'AuctionOrderUsedList',
-                    component: () => import(/* webpackChunkName: "auctionOrderList" */ '@/views/AuctionOrderUsedList.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "auctionOrderList" */ '@/views/AuctionOrderUsedList.vue'),
                     meta: {
                         title: '拍卖订单'
                     }
@@ -753,8 +754,7 @@ const router = new Router({
                 {
                     path: '/auctionUsedList',
                     name: 'AuctionUsedList',
-                    component: () =>
-                        import(/* webpackChunkName: "auctionUsedList" */ '@/views/AuctionUsedList.vue'),
+                    component: () => import(/* webpackChunkName: "auctionUsedList" */ '@/views/AuctionUsedList.vue'),
                     meta: {
                         title: '拍卖'
                     }
@@ -838,8 +838,7 @@ const router = new Router({
                 {
                     path: '/cache',
                     name: 'cache',
-                    component: () =>
-                        import(/* webpackChunkName: "cache" */ '@/views/Cache.vue'),
+                    component: () => import(/* webpackChunkName: "cache" */ '@/views/Cache.vue'),
                     meta: {
                         title: '缓存清理'
                     }
@@ -849,169 +848,202 @@ const router = new Router({
                     name: 'MessageEdit',
                     component: () => import(/* webpackChunkName: "messageEdit" */ '@/views/MessageEdit.vue'),
                     meta: {
-                        title: '留言编辑',
-                    },
+                        title: '留言编辑'
+                    }
                 },
                 {
                     path: '/messageList',
                     name: 'MessageList',
                     component: () => import(/* webpackChunkName: "messageList" */ '@/views/MessageList.vue'),
                     meta: {
-                        title: '留言',
-                    },
+                        title: '留言'
+                    }
                 },
                 {
                     path: '/destroyRecordEdit',
                     name: 'DestroyRecordEdit',
-                    component: () => import(/* webpackChunkName: "destroyRecordEdit" */ '@/views/DestroyRecordEdit.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "destroyRecordEdit" */ '@/views/DestroyRecordEdit.vue'),
                     meta: {
-                       title: '销毁积分记录编辑',
-                    },
+                        title: '销毁积分记录编辑'
+                    }
                 },
                 {
                     path: '/destroyRecordList',
                     name: 'DestroyRecordList',
-                    component: () => import(/* webpackChunkName: "destroyRecordList" */ '@/views/DestroyRecordList.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "destroyRecordList" */ '@/views/DestroyRecordList.vue'),
                     meta: {
-                       title: '销毁积分记录',
-                    },
-               },
+                        title: '销毁积分记录'
+                    }
+                },
                 {
                     path: '/tradingAccountEdit',
                     name: 'TradingAccountEdit',
-                    component: () => import(/* webpackChunkName: "tradingAccountEdit" */ '@/views/TradingAccountEdit.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "tradingAccountEdit" */ '@/views/TradingAccountEdit.vue'),
                     meta: {
-                       title: '大智慧账户编辑',
-                    },
+                        title: '大智慧账户编辑'
+                    }
                 },
                 {
                     path: '/tradingAccountList',
                     name: 'TradingAccountList',
-                    component: () => import(/* webpackChunkName: "tradingAccountList" */ '@/views/TradingAccountList.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "tradingAccountList" */ '@/views/TradingAccountList.vue'),
                     meta: {
-                       title: '大智慧账户',
-                    },
-               },
+                        title: '大智慧账户'
+                    }
+                },
                 {
                     path: '/assetLockEdit',
                     name: 'AssetLockEdit',
                     component: () => import(/* webpackChunkName: "assetLockEdit" */ '@/views/AssetLockEdit.vue'),
                     meta: {
-                       title: '锁仓编辑',
-                    },
+                        title: '锁仓编辑'
+                    }
                 },
                 {
                     path: '/assetLockList',
                     name: 'AssetLockList',
                     component: () => import(/* webpackChunkName: "assetLockList" */ '@/views/AssetLockList.vue'),
                     meta: {
-                       title: '锁仓',
-                    },
-               },
+                        title: '锁仓'
+                    }
+                },
                 {
                     path: '/recordRankEdit',
                     name: 'RecordRankEdit',
                     component: () => import(/* webpackChunkName: "recordRankEdit" */ '@/views/RecordRankEdit.vue'),
                     meta: {
-                       title: '排行编辑',
-                    },
+                        title: '排行编辑'
+                    }
                 },
                 {
                     path: '/recordRankList',
                     name: 'RecordRankList',
                     component: () => import(/* webpackChunkName: "recordRankList" */ '@/views/RecordRankList.vue'),
                     meta: {
-                       title: '排行',
-                    },
-               },
-               {
-                   path: '/userHoldCountList',
-                   name: 'UserHoldCountList',
-                   component: () => import(/* webpackChunkName: "userHoldCountList" */ '@/views/UserHoldCountList.vue'),
-                   meta: {
-                      title: '用户持仓统计',
-                   },
-               },
+                        title: '排行'
+                    }
+                },
+                {
+                    path: '/userHoldCountList',
+                    name: 'UserHoldCountList',
+                    component: () =>
+                        import(/* webpackChunkName: "userHoldCountList" */ '@/views/UserHoldCountList.vue'),
+                    meta: {
+                        title: '用户持仓统计'
+                    }
+                },
                 {
                     path: '/bonusGiveEdit',
                     name: 'BonusGiveEdit',
                     component: () => import(/* webpackChunkName: "bonusGiveEdit" */ '@/views/BonusGiveEdit.vue'),
                     meta: {
-                       title: '奖金发放编辑',
-                    },
+                        title: '奖金发放编辑'
+                    }
                 },
                 {
                     path: '/bonusGiveList',
                     name: 'BonusGiveList',
                     component: () => import(/* webpackChunkName: "bonusGiveList" */ '@/views/BonusGiveList.vue'),
                     meta: {
-                       title: '奖金发放',
-                    },
-               },
+                        title: '奖金发放'
+                    }
+                },
                 {
                     path: '/rarityLabelEdit',
                     name: 'RarityLabelEdit',
                     component: () => import(/* webpackChunkName: "rarityLabelEdit" */ '@/views/RarityLabelEdit.vue'),
                     meta: {
-                       title: '稀有度标签编辑',
-                    },
+                        title: '稀有度标签编辑'
+                    }
                 },
                 {
                     path: '/rarityLabelList',
                     name: 'RarityLabelList',
                     component: () => import(/* webpackChunkName: "rarityLabelList" */ '@/views/RarityLabelList.vue'),
                     meta: {
-                       title: '稀有度标签',
-                    },
-               },
+                        title: '稀有度标签'
+                    }
+                },
                 {
                     path: '/onOffEdit',
                     name: 'OnOffEdit',
                     component: () => import(/* webpackChunkName: "onOffEdit" */ '@/views/OnOffEdit.vue'),
                     meta: {
-                       title: '开关编辑',
-                    },
+                        title: '开关编辑'
+                    }
                 },
                 {
                     path: '/onOffList',
                     name: 'OnOffList',
                     component: () => import(/* webpackChunkName: "onOffList" */ '@/views/OnOffList.vue'),
                     meta: {
-                       title: '开关',
-                    },
-               },
+                        title: '开关'
+                    }
+                },
                 {
                     path: '/metaSpatialInfoEdit',
                     name: 'MetaSpatialInfoEdit',
-                    component: () => import(/* webpackChunkName: "metaSpatialInfoEdit" */ '@/views/MetaSpatialInfoEdit.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "metaSpatialInfoEdit" */ '@/views/MetaSpatialInfoEdit.vue'),
                     meta: {
-                       title: '元宇宙空间信息编辑',
-                    },
+                        title: '元宇宙空间信息编辑'
+                    }
                 },
                 {
                     path: '/metaSpatialInfoList',
                     name: 'MetaSpatialInfoList',
-                    component: () => import(/* webpackChunkName: "metaSpatialInfoList" */ '@/views/MetaSpatialInfoList.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "metaSpatialInfoList" */ '@/views/MetaSpatialInfoList.vue'),
                     meta: {
-                       title: '元宇宙空间信息',
-                    },
-               },
+                        title: '元宇宙空间信息'
+                    }
+                },
                 {
                     path: '/metaPlayerWearEdit',
                     name: 'MetaPlayerWearEdit',
-                    component: () => import(/* webpackChunkName: "metaPlayerWearEdit" */ '@/views/MetaPlayerWearEdit.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "metaPlayerWearEdit" */ '@/views/MetaPlayerWearEdit.vue'),
                     meta: {
-                       title: '元宇宙服饰编辑',
-                    },
+                        title: '元宇宙服饰编辑'
+                    }
                 },
                 {
                     path: '/metaPlayerWearList',
                     name: 'MetaPlayerWearList',
-                    component: () => import(/* webpackChunkName: "metaPlayerWearList" */ '@/views/MetaPlayerWearList.vue'),
+                    component: () =>
+                        import(/* webpackChunkName: "metaPlayerWearList" */ '@/views/MetaPlayerWearList.vue'),
                     meta: {
-                       title: '元宇宙服饰',
-                    },
-               }
+                        title: '元宇宙服饰'
+                    }
+                },
+                {
+                    path: '/companyEdit',
+                    name: 'CompanyEdit',
+                    component: () => import(/* webpackChunkName: "companyEdit" */ '@/views/CompanyEdit.vue'),
+                    meta: {
+                        title: '企业管理编辑'
+                    }
+                },
+                {
+                    path: '/companyList',
+                    name: 'CompanyList',
+                    component: () => import(/* webpackChunkName: "companyList" */ '@/views/CompanyList.vue'),
+                    meta: {
+                        title: '企业管理'
+                    }
+                },
+                {
+                    path: '/companyAdmin',
+                    name: 'CompanyAdmin',
+                    component: () => import(/* webpackChunkName: "companyAdmin" */ '@/views/CompanyAdmin.vue'),
+                    meta: {
+                        title: '企业管理员'
+                    }
+                }
                 /**INSERT_LOCATION**/
             ]
         },

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

@@ -78,7 +78,7 @@ export default {
     created() {
         if (this.$route.query.id) {
             this.$http
-                .get(`/user/get/${this.$route.query.id}`)
+                .get(`/user/adminGet/${this.$route.query.id}`)
                 .then(res => {
                     this.formData = res;
                 })

+ 258 - 0
src/main/vue/src/views/CompanyAdmin.vue

@@ -0,0 +1,258 @@
+<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="username" label="用户名"> </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间"></el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="100">
+                <template slot-scope="{ row }">
+                    <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>
+        <el-dialog title="新增" :visible.sync="showDialog">
+            <el-form :model="form" :rules="rules" ref="form">
+                <el-form-item prop="username" label="用户名">
+                    <el-input v-model="form.username" placeholder="用户名不能包含特殊字符"></el-input>
+                </el-form-item>
+                <el-form-item prop="password" label="密码">
+                    <el-input
+                        v-model="form.password"
+                        type="password"
+                        placeholder="密码长度至少为8位,且必须包含大小写字母和数字"
+                    ></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer">
+                <el-button size="mini" @click="showDialog = false">取消</el-button>
+                <el-button size="mini" type="primary" @click="save">确定</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+    name: 'CompanyList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/user/adminAll',
+            downloading: false,
+            companyId: null,
+            showDialog: false,
+            form: {
+                username: null,
+                password: null
+            },
+            rules: {
+                username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
+                password: [
+                    { required: true, message: '请输入密码', trigger: 'blur' },
+                    {
+                        validator: (rule, value, callback) => {
+                            if (
+                                value.length >= 8 &&
+                                /[a-z]/.test(value) &&
+                                /[A-Z]/.test(value) &&
+                                /[0-9]/.test(value)
+                            ) {
+                                callback();
+                            } else {
+                                callback(new Error('密码长度至少为8位,且必须包含大小写字母和数字'));
+                            }
+                        }
+                    }
+                ]
+            }
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        beforeCreated() {
+            if (this.$route.query.id) {
+                this.companyId = this.$route.query.id;
+            } else if (this.$store.userInfo.authorities.find(i => i.name === 'ROLE_COMPANY')) {
+                this.companyId = this.$store.userInfo.companyId;
+            }
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false, admin: true, companyId: this.companyId } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$refs.form && this.$refs.form.clearValidate();
+            this.form = { username: '', password: '' };
+            this.showDialog = true;
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/companyEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/company/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(`/company/delAdmin`, { companyId: this.companyId, userId: row.id });
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        },
+        adminMgmt(row) {
+            this.selected = row;
+            this.adminList = [];
+            this.showAdminList = true;
+            this.$http
+                .post(
+                    '/user/adminAll',
+                    { del: false, size: 10000, query: { admin: true, companyId: this.selected.id } },
+                    { body: 'json' }
+                )
+                .then(res => {
+                    this.adminList = res.content;
+                });
+        },
+        save() {
+            this.$refs.form
+                .validate()
+                .then(() => {
+                    this.$http
+                        .post('/company/addAdmin', { companyId: this.companyId, ...this.form })
+                        .then(res => {
+                            this.$message.success('添加成功');
+                            this.getData();
+                            this.showDialog = false;
+                        })
+                        .catch(e => {
+                            if (e.error && e.error.includes('UK_sb8bbouer5wak8vyiiy4pf2bx')) {
+                                this.$message.error('用户名已存在');
+                                return;
+                            }
+                            this.$message.error(e.error || '添加失败');
+                        });
+                })
+                .catch(e => {});
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 61 - 156
src/main/vue/src/views/CompanyEdit.vue

@@ -1,15 +1,11 @@
 <template>
     <div class="edit-view">
         <page-title>
-            <el-button @click="$router.go(-1)">取消</el-button>
-            <el-button
-                @click="del"
-                :loading="$store.state.fetchingData"
-                type="danger"
-                v-if="formData.id && formData.id !== 1"
-                >删除
+            <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="$store.state.fetchingData" type="primary">保存</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">
@@ -17,59 +13,29 @@
                     :model="formData"
                     :rules="rules"
                     ref="form"
-                    label-width="80px"
+                    label-width="66px"
                     label-position="right"
-                    style="max-width: 500px"
+                    size="small"
+                    style="max-width: 500px;"
                 >
-                    <el-form-item prop="avatar" label="头像">
-                        <crop-upload v-model="formData.avatar"></crop-upload>
+                    <el-form-item prop="name" label="名称">
+                        <el-input v-model="formData.name"></el-input>
                     </el-form-item>
-                    <el-form-item prop="username" label="用户名">
-                        <el-input v-model="formData.username"></el-input>
-                        <div class="gen" @dblclick="gen"></div>
+                    <el-form-item prop="description" label="描述">
+                        <el-input type="textarea" v-model="formData.description"></el-input>
                     </el-form-item>
-                    <el-form-item prop="nickname" label="昵称">
-                        <el-input v-model="formData.nickname"></el-input>
+                    <el-form-item prop="logo" label="LOGO">
+                        <single-upload v-model="formData.logo"></single-upload>
                     </el-form-item>
-                    <el-form-item v-if="formData.id" label="密码">
-                        <el-button type="primary" plain @click="resetPassword" size="mini">重置 </el-button>
+                    <el-form-item prop="disabled" label="禁用">
+                        <el-switch v-model="formData.disabled"></el-switch>
                     </el-form-item>
-                    <el-form-item v-else prop="password" label="密码">
-                        <el-input v-model="formData.password"></el-input>
-                    </el-form-item>
-                    <el-form-item prop="phone" label="手机">
-                        <el-input v-model="formData.phone" :disabled="!!formData.id"></el-input>
-                    </el-form-item>
-                    <el-form-item prop="intro" label="简介">
-                        <el-input
-                            v-model="formData.intro"
-                            placeholder="200字以内"
-                            maxlength="200"
-                            type="textarea"
-                            autosize
-                        ></el-input>
-                    </el-form-item>
-                    <!-- <el-form-item prop="authorities" label="角色">
-                        <el-select
-                            v-model="formData.authorities"
-                            multiple
-                            placeholder="请选择"
-                            value-key="name"
-                            style="width: 100%"
-                        >
-                            <el-option
-                                v-for="item in authorities"
-                                :key="item.name"
-                                :label="item.description"
-                                :value="item"
-                            >
-                            </el-option>
-                        </el-select>
-                    </el-form-item> -->
-                    <el-form-item>
-                        <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
-                        <el-button @click="del" :disabled="saving" type="danger" v-if="formData.id && formData.id !== 1"
-                            >删除
+                    <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>
@@ -79,15 +45,12 @@
     </div>
 </template>
 <script>
-import randomstring from 'randomstring';
-import faker from 'faker';
-faker.locale = 'zh_CN';
-console.log(faker);
 export default {
+    name: 'CompanyEdit',
     created() {
         if (this.$route.query.id) {
             this.$http
-                .get(`/user/get/${this.$route.query.id}`)
+                .get('company/get/' + this.$route.query.id)
                 .then(res => {
                     this.formData = res;
                 })
@@ -96,56 +59,43 @@ export default {
                     this.$message.error(e.error);
                 });
         }
-        this.$http
-            .get('/authority/all')
-            .then(res => {
-                this.authorities = res;
-            })
-            .catch(e => {
-                console.log(e);
-            });
     },
     data() {
         return {
             saving: false,
             formData: {
-                company: true,
-                username:
-                    '0x' +
-                    randomstring.generate({
-                        length: 6,
-                        charset: 'alphabetic',
-                        capitalization: 'lowercase'
-                    }),
-                avatar:
-                    parseInt(Math.random() * 10) % 2 === 1
-                        ? 'https://awesomeadmin.oss-cn-hangzhou.aliyuncs.com/image/avatar_male.png'
-                        : 'https://awesomeadmin.oss-cn-hangzhou.aliyuncs.com/image/avatar_female.png',
-                authorities: [
-                    { name: 'ROLE_COMPANY', description: '企业' },
-                    { name: 'ROLE_USER', description: '普通用户' }
-                ]
+                disabled: false
             },
             rules: {
-                avatar: [{ required: true, message: '请上传头像', trigger: 'blur' }],
-                username: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
-                nickname: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
-                password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
-                phone: [
-                    // { required: true, message: '请输入密码', trigger: 'blur' },
+                name: [
                     {
-                        pattern: /^1[3-9]\d{9}$/,
-                        message: '请输入正确的手机号',
+                        required: true,
+                        message: '请输入名称',
                         trigger: 'blur'
                     }
                 ],
-                authorities: [{ required: true, message: '请选择角色', trigger: 'blur' }],
-                intro: [{ required: true, message: '请输入简介', trigger: 'blur' }]
-            },
-            authorities: [
-                { name: 'ROLE_COMPANY', description: '企业' },
-                { name: 'ROLE_USER', description: '普通用户' }
-            ]
+                logo: [
+                    {
+                        required: true,
+                        message: '请输入LOGO',
+                        trigger: 'blur'
+                    }
+                ],
+                adminUserId: [
+                    {
+                        required: true,
+                        message: '请输入管理员',
+                        trigger: 'blur'
+                    }
+                ],
+                disabled: [
+                    {
+                        required: true,
+                        message: '请输入禁用',
+                        trigger: 'blur'
+                    }
+                ]
+            }
         };
     },
     methods: {
@@ -159,21 +109,15 @@ export default {
             });
         },
         submit() {
+            let data = { ...this.formData };
+
             this.saving = true;
-            this.formData.company = true;
             this.$http
-                .post(this.formData.id ? '/user/save' : '/user/create', this.formData, { body: 'json' })
+                .post('/company/save', data, { body: 'json' })
                 .then(res => {
                     this.saving = false;
                     this.$message.success('成功');
-                    this.formData = res;
-                    this.$router
-                        .replace({
-                            query: {
-                                id: res.id
-                            }
-                        })
-                        .catch(_ => {});
+                    this.$router.go(-1);
                 })
                 .catch(e => {
                     console.log(e);
@@ -181,62 +125,23 @@ export default {
                     this.$message.error(e.error);
                 });
         },
-        del() {
-            this.$confirm('确认删除吗?', '提示', { type: 'warning' })
+        onDelete() {
+            this.$confirm('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
                 .then(() => {
-                    return this.$http.post(`/user/del/${this.formData.id}`);
+                    return this.$http.post(`/company/del/${this.formData.id}`);
                 })
-                .then(res => {
+                .then(() => {
                     this.$message.success('删除成功');
                     this.$router.go(-1);
                 })
                 .catch(e => {
-                    if ('cancel' !== e) {
-                        this.$message.error(e.error || '删除失败');
+                    if (e !== 'cancel') {
+                        console.log(e);
+                        this.$message.error((e || {}).error || '删除失败');
                     }
                 });
-        },
-        resetPassword() {
-            this.$prompt('请输入新密码', '重置密码', { inputType: 'password' })
-                .then(res => {
-                    console.log(res);
-                    if (res.value) {
-                        this.$alert('确定重置密码?', '提示', {
-                            showCancelButton: true
-                        })
-                            .then(() => {
-                                return this.$http.post('/user/setPasswordAdmin', {
-                                    userId: this.formData.id,
-                                    password: res.value
-                                });
-                            })
-                            .then(res => {
-                                this.$message.success('密码重置成功');
-                            })
-                            .catch(() => {
-                                this.$message.error(res.error || '重置密码失败');
-                            });
-                    }
-                })
-                .catch(() => {});
-        },
-        gen() {
-            const card = faker.helpers.createCard();
-            this.formData.username = card.username;
-            this.formData.nickname = card.name;
-            this.formData.phone = card.phone;
-            this.$message('ok');
-            console.log(card);
         }
     }
 };
 </script>
-<style lang="less" scoped>
-.gen {
-    position: absolute;
-    top: 0;
-    right: -50px;
-    width: 50px;
-    height: 32px;
-}
-</style>
+<style lang="less" scoped></style>

+ 74 - 122
src/main/vue/src/views/CompanyList.vue

@@ -1,15 +1,33 @@
 <template>
     <div class="list-view">
         <page-title>
-            <el-button @click="addRow" type="primary" icon="el-icon-plus" :loading="downloading" class="filter-item">
+            <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" class="filter-item">
+            <el-button
+                @click="download"
+                icon="el-icon-upload2"
+                :loading="downloading"
+                :disabled="fetchingData"
+                class="filter-item"
+            >
                 导出
-            </el-button> -->
+            </el-button>
         </page-title>
         <div class="filters-container">
-            <el-input placeholder="搜索..." v-model="search" clearable class="filter-item search">
+            <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>
@@ -17,36 +35,50 @@
             :data="tableData"
             row-key="id"
             ref="table"
-            height="tableHeight"
             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="username" label="用户名"> </el-table-column>
-            <el-table-column prop="nickname" label="昵称"> </el-table-column>
-            <el-table-column label="头像">
+            <el-table-column prop="name" label="名"> </el-table-column>
+            <el-table-column prop="description" label="描述"> </el-table-column>
+            <el-table-column prop="logo" label="LOGO">
                 <template slot-scope="{ row }">
                     <el-image
                         style="width: 30px; height: 30px"
-                        :src="row.avatar"
+                        :src="row.logo"
                         fit="cover"
-                        :preview-src-list="[row.avatar]"
+                        :preview-src-list="[row.logo]"
                     ></el-image>
                 </template>
             </el-table-column>
-            <el-table-column prop="showroomNum" label="展厅数量"> </el-table-column>
-            <el-table-column prop="boxShowroomNum" label="盲盒展厅数量"> </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" width="180">
+            <el-table-column prop="adminUserId" label="管理员"> </el-table-column>
+            <el-table-column prop="disabled" label="禁用">
                 <template slot-scope="{ row }">
-                    <el-button @click="chooseShowroomType(row)" type="success" size="mini" plain>发放展厅</el-button>
+                    <el-tag :type="row.disabled ? '' : 'info'">{{ row.disabled }}</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="220">
+                <template slot-scope="{ row }">
+                    <el-button @click="adminMgmt(row)" size="mini">管理员</el-button>
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
+                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
                 </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"
@@ -59,57 +91,32 @@
             >
             </el-pagination>
         </div>
-        <el-dialog :visible.sync="showDialog" title="选择类型" width="500px" center>
-            <el-form :model="addShowroom" label-width="100px" size="mini" :rules="rules" ref="form">
-                <el-form-item label="发放类型" prop="type">
-                    <el-radio-group v-model="addShowroom.type">
-                        <el-radio label="COMPANY">普通展厅</el-radio>
-                        <el-radio label="COMPANY_BOX">盲盒展厅</el-radio>
-                    </el-radio-group>
-                </el-form-item>
-                <el-form-item>
-                    <el-button type="primary" size="mini" @click="createShowroom">确定</el-button>
-                    <el-button @click="showDialog = false">取消</el-button>
-                </el-form-item>
-            </el-form>
-        </el-dialog>
+        <el-dialog title="管理员"></el-dialog>
     </div>
 </template>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
-import ClipboardJS from 'clipboard';
-const clickData = {};
+
 export default {
+    name: 'CompanyList',
     mixins: [pageableTable],
     data() {
         return {
             multipleMode: false,
             search: '',
-            url: '/user/companyAll',
-            downloading: false,
-            showDialog: false,
-            addShowroom: {},
-            rules: {
-                type: [
-                    {
-                        required: true,
-                        message: '请选择类型',
-                        trigger: 'blur'
-                    }
-                ]
-            }
+            url: '/company/all',
+            downloading: false
         };
     },
     computed: {
-        ...mapState([]),
         selection() {
             return this.$refs.table.selection.map(i => i.id);
         }
     },
     methods: {
         beforeGetData() {
-            return { search: this.search, query: { company: true } };
+            return { search: this.search, query: { del: false } };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
@@ -136,7 +143,10 @@ export default {
         download() {
             this.downloading = true;
             this.$axios
-                .get('/user/excel', { responseType: 'blob' })
+                .get('/company/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000 }
+                })
                 .then(res => {
                     console.log(res);
                     this.downloading = false;
@@ -163,84 +173,26 @@ export default {
         operation2() {
             this.$message('操作2');
         },
-        clickId(row) {
-            if (row.id !== clickData.id) {
-                clickData.id = row.id;
-                clickData.c = 0;
-            }
-            clickData.c = (clickData.c || 0) + 1;
-            if (clickData.i) {
-                clearInterval(clickData.i);
-            }
-            clickData.i = setTimeout(_ => {
-                clickData.c = 0;
-            }, 200);
-            if (clickData.c === 5) {
-                this.$http
-                    .get(`/user/getToken/${row.id}`)
-                    .then(res => {
-                        let el = document.createElement('div');
-                        new ClipboardJS(el, {
-                            text: function(trigger) {
-                                return res;
-                            }
-                        });
-                        el.click();
-                        this.$message.success('已复制Token');
-                        clickData.c = 0;
-                    })
-                    .catch(e => {
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/company/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
                         this.$message.error(e.error);
-                    });
-            }
-        },
-        chooseShowroomType(row) {
-            this.showDialog = true;
-            this.addShowroom.id = row.id;
+                    }
+                });
         },
-        createShowroom() {
-            // this.$confirm('确认发布展厅吗?', '提示', {
-            //     confirmButtonText: '确定',
-            //     cancelButtonText: '取消',
-            //     type: 'warning'
-            // })
-            //     .then(() => {
-            //         return this.$http.post('/showroom/create', {
-            //             userId: this.addShowroom.id,
-            //             type: this.addShowroom.type
-            //         });
-            //     })
-            //     .then(() => {
-            //         this.saving = false;
-            //         this.$message.success('成功');
-            //         this.getData();
-            //     })
-            //     .catch(e => {
-            //         console.log(e);
-            //         this.saving = false;
-            //         if (e !== 'cancel') {
-            //             this.$message.error(e.error);
-            //         }
-            //     });
-            this.$refs.form.validate(valid => {
-                if (valid) {
-                    this.$http
-                        .post('/showroom/create', {
-                            userId: this.addShowroom.id,
-                            type: this.addShowroom.type
-                        })
-                        .then(() => {
-                            this.$message.success('成功');
-                            this.showDialog = false;
-                            this.getData();
-                        })
-                        .catch(e => {
-                            this.$message.error(e.error);
-                            this.showDialog = false;
-                            console.log(e);
-                        });
-                } else {
-                    return false;
+        adminMgmt(row) {
+            this.$router.push({
+                path: '/companyAdmin',
+                query: {
+                    id: row.id
                 }
             });
         }

+ 3 - 2
src/main/vue/src/views/Menus.vue

@@ -94,8 +94,9 @@ export default {
                     i.name === 'ROLE_OPERATOR' ||
                     i.name === 'ROLE_NEWS' ||
                     i.name === 'ROLE_COMPANY' ||
-                    i.name === 'ROLE_MESSAGE' || 
-                    i.name === 'ROLE_SHOWROOM'
+                    i.name === 'ROLE_MESSAGE' ||
+                    i.name === 'ROLE_SHOWROOM' ||
+                    i.name === 'ROLE_SAAS'
             );
         });
     },