Эх сурвалжийг харах

feat: 管理员sip优化
1. 管理员sip配置绑定优化

kindring 1 жил өмнө
parent
commit
a2ab9066ff
25 өөрчлөгдсөн 789 нэмэгдсэн , 287 устгасан
  1. 2 1
      src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java
  2. 40 3
      src/main/java/com/genersoft/iot/vmp/conf/security/StpInterfaceImpl.java
  3. 1 5
      src/main/java/com/genersoft/iot/vmp/conf/security/dto/LoginUser.java
  4. 10 3
      src/main/java/com/genersoft/iot/vmp/service/IAdminService.java
  5. 9 1
      src/main/java/com/genersoft/iot/vmp/service/ISipConfigService.java
  6. 33 3
      src/main/java/com/genersoft/iot/vmp/service/impl/AdminServiceImpl.java
  7. 41 3
      src/main/java/com/genersoft/iot/vmp/service/impl/SipConfigService.java
  8. 7 6
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
  9. 53 26
      src/main/java/com/genersoft/iot/vmp/storager/dao/AdminMapper.java
  10. 6 3
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
  11. 34 8
      src/main/java/com/genersoft/iot/vmp/storager/dao/SipConfigMapper.java
  12. 20 12
      src/main/java/com/genersoft/iot/vmp/storager/dao/dto/AdminAccount.java
  13. 7 4
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
  14. 10 2
      src/main/java/com/genersoft/iot/vmp/utils/DeviceHelper.java
  15. 18 4
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
  16. 11 8
      src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
  17. 84 2
      src/main/java/com/genersoft/iot/vmp/vmanager/server/sipController.java
  18. 0 75
      src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java
  19. 89 88
      src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
  20. 1 1
      src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java
  21. 66 10
      web_src/src/components/DeviceList.vue
  22. 207 0
      web_src/src/components/com/sipBind.vue
  23. 2 2
      web_src/src/components/com/sipConfigEdit.vue
  24. 0 10
      web_src/src/components/dialog/addUser.vue
  25. 38 7
      web_src/src/components/setting/SipConfigs.vue

+ 2 - 1
src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java

@@ -70,9 +70,10 @@ public class SecurityUtils {
 
     /**
      * 获取当前登录用户ID
+     *
      * @return
      */
-    public static int getUserId(){
+    public static String getUserId() {
         LoginUser user = getUserInfo();
         return user.getId();
     }

+ 40 - 3
src/main/java/com/genersoft/iot/vmp/conf/security/StpInterfaceImpl.java

@@ -1,8 +1,11 @@
 package com.genersoft.iot.vmp.conf.security;
 
 import cn.dev33.satoken.stp.StpInterface;
+import com.genersoft.iot.vmp.service.IAdminService;
+import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.ArrayList;
@@ -14,6 +17,10 @@ import java.util.List;
 @Component    // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
 public class StpInterfaceImpl implements StpInterface {
     private Logger logger = LoggerFactory.getLogger(StpInterfaceImpl.class);
+
+    @Autowired
+    private IAdminService adminService;
+
     /**
      * 返回一个账号所拥有的权限码集合
      */
@@ -37,19 +44,49 @@ public class StpInterfaceImpl implements StpInterface {
     public List<String> getRoleList(Object loginId, String loginKey) {
         logger.debug("[用户权限] 获取用户角色 {}: {}", loginId, loginKey);
         // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
-        List<String> list = new ArrayList<>();
+        List<String> list;
+
         switch (loginKey) {
             case "admin":
 //                StpAdminUtil.checkLogin();
-                list.add("admin");
+                list = getAdminRoleList(loginId);
                 break;
             case "user":
 //                StpUserUtil.checkLogin();
-                list.add("user");
+                list = getUserRoleList(loginId);
                 break;
             default:
+                list = new ArrayList<>();
                 break;
         }
         return list;
     }
+
+    /**
+     * 获取管理员权限
+     *
+     * @param loginId 管理员id
+     */
+    public List<String> getAdminRoleList(Object loginId) {
+        AdminAccount adminAccount = adminService.getUserById(loginId.toString());
+        List<String> list = new ArrayList<>();
+        list.add("admin");
+        if (adminAccount.isPrimaryAdminFlag()) {
+            list.add("primary");
+        } else {
+            list.add("sub");
+        }
+        return list;
+    }
+
+    /**
+     * 获取用户权限
+     *
+     * @param loginId 管理员id
+     */
+    public List<String> getUserRoleList(Object loginId) {
+        List<String> list = new ArrayList<>();
+        list.add("user");
+        return list;
+    }
 }

+ 1 - 5
src/main/java/com/genersoft/iot/vmp/conf/security/dto/LoginUser.java

@@ -92,14 +92,10 @@ public class LoginUser implements UserDetails, CredentialsContainer {
     }
 
 
-    public int getId() {
+    public String getId() {
         return adminAccount.getId();
     }
 
-    public Role getRole() {
-        return adminAccount.getRole();
-    }
-
 
     public String getAccessToken() {
         return accessToken;

+ 10 - 3
src/main/java/com/genersoft/iot/vmp/service/IAdminService.java

@@ -10,7 +10,11 @@ public interface IAdminService {
 
     AdminAccount getUser(String username, String password);
 
-    boolean changePassword(int id, String password);
+    int getUserCount();
+
+    boolean registerAdmin(String username, String password);
+
+    boolean changePassword(String id, String password);
 
     AdminAccount getUserByUsername(String username);
 
@@ -28,9 +32,9 @@ public interface IAdminService {
 
     PageInfo<AdminAccount> getUsers(int page, int count);
 
-    int changePushKey(int id, String pushKey);
+    int changePushKey(String id, String pushKey);
 
-    String getPushKey(int id);
+    String getPushKey(String id);
 
     /**
      * 获取设备, 根据管理员ID和设备ID
@@ -58,4 +62,7 @@ public interface IAdminService {
      */
     List<Device> getAdminDevices(String adminId);
 
+    PageInfo<Device> searchDevicesByAdminId(
+            String adminId, String domain, Boolean online, int page, int count);
+
 }

+ 9 - 1
src/main/java/com/genersoft/iot/vmp/service/ISipConfigService.java

@@ -1,8 +1,11 @@
 package com.genersoft.iot.vmp.service;
 
 import com.genersoft.iot.vmp.gb28181.bean.SipUserConfig;
+import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
 import com.github.pagehelper.PageInfo;
 
+import java.util.List;
+
 public interface ISipConfigService {
     /**
      * 获取对应的sip配置信息
@@ -22,6 +25,7 @@ public interface ISipConfigService {
      */
     PageInfo<SipUserConfig> getSipConfigsById(String adminId, int page, int limit);
 
+    List<SipUserConfig> getAllSipConfigsById(String adminId);
 
     /**
      * 获取指定配置信息
@@ -46,7 +50,11 @@ public interface ISipConfigService {
      */
     boolean addSipConfig(String adminId, SipUserConfig sipConfig);
 
+    boolean deleteSipConfig(String sipId);
+
+    boolean unbindSipConfig(String adminId, String sipId);
 
-    boolean deleteSipConfig(String adminId, String sipId);
+    boolean bindSipConfig(String adminId, String sipId);
 
+    List<AdminAccount> getSipAdmin(String sipId);
 }

+ 33 - 3
src/main/java/com/genersoft/iot/vmp/service/impl/AdminServiceImpl.java

@@ -5,12 +5,14 @@ import com.genersoft.iot.vmp.service.IAdminService;
 import com.genersoft.iot.vmp.storager.dao.AdminMapper;
 import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
 import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
+import com.genersoft.iot.vmp.utils.DateUtil;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
 import org.springframework.util.ObjectUtils;
 
 import java.util.List;
@@ -32,7 +34,25 @@ public class AdminServiceImpl implements IAdminService {
     }
 
     @Override
-    public boolean changePassword(int id, String password) {
+    public int getUserCount() {
+        List<AdminAccount> adminAccounts = adminMapper.getAllAdmin();
+        return adminAccounts.size();
+    }
+
+    public boolean registerAdmin(String username, String password) {
+        AdminAccount adminAccount = new AdminAccount();
+        adminAccount.setUsername(username);
+        adminAccount.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
+        //新增用户的pushKey的生成规则为md5(时间戳+用户名)
+        adminAccount.setPushKey(DigestUtils.md5DigestAsHex((System.currentTimeMillis() + password).getBytes()));
+        adminAccount.setCreateTime(DateUtil.getNow());
+        adminAccount.setUpdateTime(DateUtil.getNow());
+        return adminMapper.addAdmin(adminAccount) > 0;
+    }
+
+
+    @Override
+    public boolean changePassword(String id, String password) {
 
         AdminAccount adminAccount = adminMapper.selectById(id);
         adminAccount.setPassword(password);
@@ -91,12 +111,12 @@ public class AdminServiceImpl implements IAdminService {
     }
 
     @Override
-    public int changePushKey(int id, String pushKey) {
+    public int changePushKey(String id, String pushKey) {
         return adminMapper.changePushKey(id, pushKey);
     }
 
     @Override
-    public String getPushKey(int id) {
+    public String getPushKey(String id) {
         List<AdminAccount> adminAccounts = adminMapper.getPushKey(id);
         if (!adminAccounts.isEmpty()) {
             return adminAccounts.get(0).getPushKey();
@@ -114,9 +134,19 @@ public class AdminServiceImpl implements IAdminService {
         return adminMapper.getDevicesByAdminId(adminId);
     }
 
+    public PageInfo<Device> searchDevicesByAdminId(
+            String adminId, String domain, Boolean online, int page, int count) {
+        PageHelper.startPage(page, count);
+
+        List<Device> all = adminMapper.searchDevice(adminId, domain, online);
+
+        return new PageInfo<>(all);
+    }
+
     //    获取某个管理员设备,根据设备国标id
     public Device getAdminDeviceBySipId(String adminId, String deviceSipId) {
 //        logger.info("getAdminDeviceBySipId get admin:{} device:{}", adminId, deviceSipId);
+        // 获取设备
         Device device = adminMapper.getAdminDeviceBySipId(adminId, deviceSipId);
         if (device == null) {
             return null;

+ 41 - 3
src/main/java/com/genersoft/iot/vmp/service/impl/SipConfigService.java

@@ -3,7 +3,9 @@ package com.genersoft.iot.vmp.service.impl;
 import com.genersoft.iot.vmp.gb28181.bean.SipUserConfig;
 import com.genersoft.iot.vmp.service.ISipConfigService;
 import com.genersoft.iot.vmp.storager.dao.SipConfigMapper;
+import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
 import com.genersoft.iot.vmp.utils.DateUtil;
+import com.genersoft.iot.vmp.utils.StpAdminUtil;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import org.slf4j.Logger;
@@ -36,10 +38,26 @@ public class SipConfigService implements ISipConfigService {
     public PageInfo<SipUserConfig> getSipConfigsById(String adminId, int page, int limit) {
         PageHelper.startPage(page, limit);
         logger.info("获取管理员{}, 的sip配置信息", adminId);
-        List<SipUserConfig> sipConfigs = sipConfigMapper.querySipConfigsByAdminId(adminId);
+        List<SipUserConfig> sipConfigs;
+        if (StpAdminUtil.hasRole("primary")) {
+            sipConfigs = sipConfigMapper.queryAllSipConfig();
+        } else {
+            sipConfigs = sipConfigMapper.querySipConfigsByAdminId(adminId);
+        }
         return new PageInfo<>(sipConfigs);
     }
 
+    public List<SipUserConfig> getAllSipConfigsById(String adminId) {
+        List<SipUserConfig> sipConfigs;
+        logger.info("获取管理员{} 所有的sip配置信息", adminId);
+        if (StpAdminUtil.hasRole("primary")) {
+            sipConfigs = sipConfigMapper.queryAllSipConfig();
+        } else {
+            sipConfigs = sipConfigMapper.querySipConfigsByAdminId(adminId);
+        }
+        return sipConfigs;
+    }
+
     @Override
     public SipUserConfig getSipConfigById(String adminId, String sipId) {
         return sipConfigMapper.querySipConfigsById(adminId, sipId);
@@ -57,8 +75,28 @@ public class SipConfigService implements ISipConfigService {
         return sipConfigMapper.addSipConfig(sipConfig) > 0;
     }
 
-    public boolean deleteSipConfig(String adminId, String sipId) {
-        return sipConfigMapper.deleteSipConfig(sipId, adminId) > 0;
+    public boolean deleteSipConfig(String sipId) {
+        // todo 删除sip配置
+        return false;
+    }
+
+    public boolean unbindSipConfig(String adminId, String sipId) {
+        return sipConfigMapper.adminUnbindSip(adminId, sipId) > 0;
+    }
+
+    public boolean bindSipConfig(String adminId, String sipId) {
+        // 判断当前管理员是否已经拥有该配置
+        SipUserConfig sipConfig = sipConfigMapper.querySipConfigsById(adminId, sipId);
+        if (sipConfig != null) {
+            logger.warn("重复绑定sip adminID:{} sipId:{}", adminId, sipId);
+            return false;
+        }
+        return sipConfigMapper.adminBindSip(adminId, sipId) > 0;
+    }
+
+    public List<AdminAccount> getSipAdmin(String sipId) {
+        List<AdminAccount> adminAccount = sipConfigMapper.getSipAdmins(sipId);
+        return adminAccount;
     }
 
 }

+ 7 - 6
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java

@@ -162,12 +162,13 @@ public interface IVideoManagerStorage {
 	public int delChannel(String deviceId, String channelId);
 
 	/**
-	 * 获取多个设备
-	 * @param page 当前页数
-	 * @param count 每页数量
-	 * @return List<Device> 设备对象数组
-	 */
-	public PageInfo<Device> queryVideoDeviceList(int page, int count,Boolean online);
+     * 获取多个设备
+     *
+     * @param page  当前页数
+     * @param count 每页数量
+     * @return List<Device> 设备对象数组
+     */
+    public PageInfo<Device> queryVideoDeviceList(int page, int count, String domain, Boolean online);
 
 	public PageInfo<AiLib> searchAiLibItems(int page,int count,int libraryId,String key);
 	public PageInfo<AiLib> searchAiLib(int page,int count,String key,Integer arithmetic);

+ 53 - 26
src/main/java/com/genersoft/iot/vmp/storager/dao/AdminMapper.java

@@ -11,10 +11,16 @@ import java.util.List;
 @Repository
 public interface AdminMapper {
 
-    @Insert("INSERT INTO user (username, password, roleId, pushKey, createTime, updateTime) VALUES" +
-            "(#{username}, #{password}, #{role.id}, #{pushKey}, #{createTime}, #{updateTime})")
+    @Insert("INSERT INTO user (username, password, pushKey, createTime, updateTime) VALUES" +
+            "(#{username}, #{password}, #{pushKey}, #{createTime}, #{updateTime})")
     int add(AdminAccount adminAccount);
 
+    @Insert("INSERT INTO " +
+            "user (username, password, pushKey, createTime, updateTime, primaryAdmin) " +
+            "VALUES" +
+            "(#{username}, #{password}, #{pushKey}, #{createTime}, #{updateTime}, '1')")
+    int addAdmin(AdminAccount adminAccount);
+
     @Update(value = {" <script>" +
             "UPDATE user " +
             "SET updateTime=#{updateTime} " +
@@ -29,30 +35,19 @@ public interface AdminMapper {
     @Delete("DELETE FROM user WHERE id != 1 and id=#{id}")
     int delete(int id);
 
-    @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id and u.username=#{username} AND u.password=#{password}")
-    @Results(id = "roleMap", value = {
-            @Result(column = "roleID", property = "role.id"),
-            @Result(column = "roleName", property = "role.name"),
-            @Result(column = "roleAuthority", property = "role.authority"),
-            @Result(column = "roleCreateTime", property = "role.createTime"),
-            @Result(column = "roleUpdateTime", property = "role.updateTime")
-    })
+    @Select("select u.* FROM user u WHERE  u.username=#{username} AND u.password=#{password}")
     AdminAccount select(String username, String password);
 
-    @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id and u.id=#{id}")
-    @ResultMap(value = "roleMap")
-    AdminAccount selectById(int id);
+    @Select("select u.*  FROM user u WHERE u.id=#{id}")
+    AdminAccount selectById(String id);
 
-    @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id and u.id=#{id}")
-    @ResultMap(value = "roleMap")
+    @Select("select u.* FROM user u WHERE u.id=#{id}")
     AdminAccount getUserById(String id);
 
-    @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id and u.username=#{username}")
-    @ResultMap(value = "roleMap")
+    @Select("select u.* FROM user u WHERE u.username=#{username}")
     AdminAccount getUserByUsername(String username);
 
-    @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id")
-    @ResultMap(value = "roleMap")
+    @Select("select * FROM user")
     List<AdminAccount> selectAll();
 
     @Select("select * from (select user.*, concat(concat(#{callId}, '_'), pushKey) as str1 from user) as u where md5(u.str1) = #{sign}")
@@ -61,22 +56,25 @@ public interface AdminMapper {
     @Select("select * from user where md5(pushKey) = #{sign}")
     List<AdminAccount> checkPushAuthorityByCallId(String sign);
 
-    @Select("select u.id, u.username,u.pushKey,u.roleId, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u join user_role r on u.roleId=r.id")
-    @ResultMap(value = "roleMap")
+    @Select("select * FROM user")
     List<AdminAccount> getUsers();
 
     @Update("update user set pushKey=#{pushKey} where id=#{id}")
-    int changePushKey(int id, String pushKey);
+    int changePushKey(String id, String pushKey);
 
     @Select("select u.id,u.pushKey from user as u where id=#{id}")
-    List<AdminAccount> getPushKey(int id);
+    List<AdminAccount> getPushKey(String id);
 
 //    SELECT dev.*
 //    FROM sip_config as sip
 //    JOIN device as dev ON sip.sipDomain = dev.domain
 //    WHERE sip.adminId = 1 AND dev.id = 15;
 
-    @Select("SELECT dev.* FROM sip_config as sip JOIN device as dev ON sip.sipDomain = dev.domain WHERE sip.adminId = #{adminId} AND dev.id = #{devId}")
+    @Select("SELECT dev.*\n" +
+            "FROM sipConfig sip\n" +
+            "JOIN devices dev ON sip.sipDomain = dev.domain\n" +
+            "JOIN adminSip a ON sip.id = a.sipId\n" +
+            "WHERE a.adminId = ${adminId} AND dev.id = ${devId};\n")
     /**
      * 获取某个管理员设备,根据设备表id
      * @param adminId 管理员id
@@ -84,7 +82,11 @@ public interface AdminMapper {
      */
     Device getDeviceByAdminIdAndDevId(String adminId, String devId);
 
-    @Select("SELECT dev.* FROM sip_config as sip JOIN device as dev ON sip.sipDomain = dev.domain WHERE sip.adminId = #{adminId} AND dev.deviceId = #{deviceSipId}")
+    @Select("SELECT dev.*\n" +
+            "FROM sipConfig sip\n" +
+            "JOIN devices dev ON sip.sipDomain = dev.domain\n" +
+            "JOIN adminSip a ON sip.id = a.sipId\n" +
+            "WHERE a.adminId = ${adminId} AND dev.deviceId = ${deviceSipId};\n")
     /**
      * 获取某个管理员设备,根据设备国标id
      * @param adminId 管理员id
@@ -92,16 +94,41 @@ public interface AdminMapper {
      */
     Device getAdminDeviceBySipId(String adminId, String deviceSipId);
 
-    @Select("SELECT dev.* FROM sip_config as sip JOIN device as dev ON sip.sipDomain = dev.domain WHERE sip.adminId = #{adminId}")
+    @Select("SELECT d.*, sc.*\n" +
+            "    FROM devices d\n" +
+            "    JOIN sipConfig sc ON d.domain = sc.sipDomain\n" +
+            "    JOIN adminSip a ON sc.id = a.sipId\n" +
+            "    WHERE a.adminId = ${adminId};")
     /**
      * 获取某个管理员账户下的所有设备
      */
     List<Device> getDevicesByAdminId(String adminId);
 
+
+    @Select(
+            " <script>" +
+                    "SELECT d.*, sc.*" +
+                    " FROM device d" +
+                    " JOIN sip_config sc ON d.domain = sc.sipDomain" +
+                    " JOIN admin_sip a ON sc.id = a.sipId" +
+                    " WHERE a.adminId = ${adminId}" +
+                    "<if test=\"domain != null\"> and d.domain=${domain}</if>" +
+                    "<if test=\"online != null\"> and d.online=${online}</if>" +
+                    " </script>"
+    )
+    /**
+     * 获取某个管理员账户下的所有设备
+     */
+    List<Device> searchDevice(String adminId, String domain, Boolean online);
+
     @Select("SELECT * FROM  device as dev  WHERE dev.domain = #{domain}")
     /**
      * 获取某个国标域的所有设备
      * @param domain 国标域
      */
     List<Device> getDevicesByDomain(String domain);
+
+    @Select("SELECT * FROM  user")
+    List<AdminAccount> getAllAdmin();
+
 }

+ 6 - 3
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java

@@ -255,11 +255,14 @@ public interface DeviceMapper {
                     "isShare," +
                     "domain," +
                     "playChannel," +
-                    "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount  FROM device de" +
-                    "<if test=\"online != null\"> where online=${online}</if>" +
+                    "(SELECT count(0) FROM device_channel WHERE " +
+                    "deviceId=de.deviceId) as channelCount  FROM device de" +
+                    " where 1 = 1 " +
+                    "<if test=\"domain != null\"> and domain=${domain}</if>" +
+                    "<if test=\"online != null\"> and online=${online}</if>" +
                     " </script>"
     )
-    List<Device> getDevices(Boolean online);
+    List<Device> getDevices(String domain, Boolean online);
 
     @Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
     int del(String deviceId);

+ 34 - 8
src/main/java/com/genersoft/iot/vmp/storager/dao/SipConfigMapper.java

@@ -10,6 +10,7 @@ package com.genersoft.iot.vmp.storager.dao;
 //private String createTime;
 
 import com.genersoft.iot.vmp.gb28181.bean.SipUserConfig;
+import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
 import org.apache.ibatis.annotations.*;
 import org.springframework.stereotype.Repository;
 
@@ -24,7 +25,6 @@ public interface SipConfigMapper {
 
     // 新增sip规则
     @Insert("INSERT INTO sip_config (" +
-            "adminId, " +
             "sipDomain, " +
             "serverId, " +
             "password," +
@@ -66,24 +66,50 @@ public interface SipConfigMapper {
     int updateSipConfig(@Param("sipUserConfig") SipUserConfig sipUserConfig, @Param("SipId") String SipId);
 
 
-    // 删除sip规则
-    @Delete("DELETE FROM sip_config WHERE id = ${sipId} adminId = ${adminId}")
-    int deleteSipConfig(String sipId, String adminId);
-
     // 查询根据域获取对应的sip配置
     @Select("SELECT * FROM sip_config WHERE sipDomain = ${sipDomain}")
     List<SipUserConfig> querySipConfigByDomain(String sipDomain);
 
-    // 获取指定管理员创建的sip规则
-    @Select("SELECT * FROM sip_config WHERE adminId = ${adminId}")
+    // 获取指定管理员拥有的sip规则
+    @Select("SELECT sc.* " +
+            "FROM sip_config sc " +
+            "JOIN admin_sip a ON sc.id = a.sipId " +
+            "WHERE a.adminId = ${adminId};")
     List<SipUserConfig> querySipConfigsByAdminId(String adminId);
 
-    @Select("SELECT * FROM sip_config WHERE adminId = ${adminId} and id =${sipId}")
+    @Select("SELECT sc.* " +
+            "FROM sip_config sc " +
+            "JOIN admin_sip a ON sc.id = a.sipId " +
+            "WHERE a.adminId = ${adminId} and sc.id = ${sipId};")
     SipUserConfig querySipConfigsById(String adminId, String sipId);
 
 
+    @Select("SELECT u.* " +
+            "FROM user u " +
+            "JOIN admin_sip a ON u.id = a.adminId " +
+            "WHERE a.sipId = ${sipId};")
+    List<AdminAccount> getSipAdmins(String sipId);
+
     // 获取所有sip规则
     @Select("SELECT * FROM sip_config")
     List<SipUserConfig> queryAllSipConfig();
 
+
+    // sip 绑定管理员
+    @Insert("INSERT INTO admin_sip (" +
+            "adminId, " +
+            "sipId " +
+            ") VALUES (" +
+            "#{adminId}, " +
+            "#{sipId} " +
+            ")"
+    )
+    int adminBindSip(String adminId, String sipId);
+
+    // 删除指定管理员的sip规则
+    @Delete("DELETE " +
+            "FROM admin_sip " +
+            "WHERE id = ${sipId} AND adminId = ${adminId};")
+    int adminUnbindSip(String adminId, String sipId);
+
 }

+ 20 - 12
src/main/java/com/genersoft/iot/vmp/storager/dao/dto/AdminAccount.java

@@ -2,19 +2,20 @@ package com.genersoft.iot.vmp.storager.dao.dto;
 
 public class AdminAccount {
 
-    private int id;
+    private String id;
     private String username;
     private String password;
     private String createTime;
     private String updateTime;
     private String pushKey;
-    private Role role;
 
-    public int getId() {
+    private String primaryAdmin;
+
+    public String getId() {
         return id;
     }
 
-    public void setId(int id) {
+    public void setId(String id) {
         this.id = id;
     }
 
@@ -50,14 +51,6 @@ public class AdminAccount {
         this.updateTime = updateTime;
     }
 
-    public Role getRole() {
-        return role;
-    }
-
-    public void setRole(Role role) {
-        this.role = role;
-    }
-
     public String getPushKey() {
         return pushKey;
     }
@@ -65,4 +58,19 @@ public class AdminAccount {
     public void setPushKey(String pushKey) {
         this.pushKey = pushKey;
     }
+
+    public String getPrimaryAdmin() {
+        return primaryAdmin;
+    }
+
+    public void setPrimaryAdmin(String primaryAdmin) {
+        this.primaryAdmin = primaryAdmin;
+    }
+
+    public boolean isPrimaryAdminFlag() {
+        if (primaryAdmin == null) {
+            return false;
+        }
+        return primaryAdmin.equals("1");
+    }
 }

+ 7 - 4
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java

@@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import com.genersoft.iot.vmp.storager.dao.*;
 import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
 import com.genersoft.iot.vmp.utils.DateUtil;
+import com.genersoft.iot.vmp.utils.StpAdminUtil;
 import com.genersoft.iot.vmp.vmanager.bean.AiAlarm;
 import com.genersoft.iot.vmp.vmanager.bean.AiLib;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
@@ -698,14 +699,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 	/**
 	 * 获取多个设备
 	 *
-	 * @param page 当前页数
+	 * @param page  当前页数
 	 * @param count 每页数量
 	 * @return PageInfo<Device> 分页设备对象数组
 	 */
 	@Override
-	public PageInfo<Device> queryVideoDeviceList(int page, int count,Boolean online) {
+	public PageInfo<Device> queryVideoDeviceList(int page, int count, String domain, Boolean online) {
 		PageHelper.startPage(page, count);
-		List<Device> all = deviceMapper.getDevices(online);
+
+		List<Device> all = deviceMapper.getDevices(domain, online);
+
 		return new PageInfo<>(all);
 	}
 
@@ -803,7 +806,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 	@Override
 	public List<Device> queryVideoDeviceList(Boolean online) {
 
-		List<Device> deviceList =  deviceMapper.getDevices(online);
+		List<Device> deviceList = deviceMapper.getDevices(null, online);
 		return deviceList;
 	}
 

+ 10 - 2
src/main/java/com/genersoft/iot/vmp/utils/DeviceHelper.java

@@ -38,8 +38,16 @@ public class DeviceHelper {
         String adminId = AuthorUtil.getAdminId();
         if (adminId != null) {
             logger.info("get admin:{} device:{}", adminId, deviceId);
-            // 管理员用户目前基本使用 国标id 进行设备操作
-            device = adminService.getAdminDeviceBySipId(adminId, deviceId);
+            // todo 获取是否为主管理员
+            boolean isPrimaryAdmin = false;
+
+            if (isPrimaryAdmin) {
+                device = deviceService.getDevice(deviceId);
+            } else {
+                // 普通管理员用户目前基本使用 国标id 进行设备操作
+                device = adminService.getAdminDeviceBySipId(adminId, deviceId);
+            }
+
         } else if (userId != null) {
             device = accountService.getAccountDevice(userId, deviceId);
         } else if (shareCode != null) {

+ 18 - 4
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

@@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
+import com.genersoft.iot.vmp.service.IAdminService;
 import com.genersoft.iot.vmp.service.IDeviceChannelService;
 import com.genersoft.iot.vmp.service.IDeviceService;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -86,12 +87,16 @@ public class DeviceQuery {
     @Autowired
     private IDeviceService deviceService;
 
+    @Autowired
+    private IAdminService adminService;
+
     @Autowired
     private DynamicTask dynamicTask;
 
     @Autowired
     private DeviceShare deviceShare;
 
+
     @Autowired
     private DeviceHelper deviceHelper;
 
@@ -294,19 +299,28 @@ public class DeviceQuery {
     @Parameter(name = "page", description = "当前页", required = true)
     @Parameter(name = "count", description = "每页查询数量", required = true)
     @Parameter(name = "online", description = "是否只查询线设备", required = false)
+    @Parameter(name = "domain", description = "国标域", required = false)
     @GetMapping("/devices")
     @Options()
     public PageInfo<Device> devices(int page,
                                     int count,
+                                    String domain,
                                     @RequestParam(value = "online", defaultValue = "false", required = false) boolean online) {
         String adminId = AuthorUtil.getAdminId();
-        String userId = AuthorUtil.getUserId();
+        Boolean isOnline = null;
         logger.info("[设备查询] 查询所有设备 {}", adminId);
-        //
         if (online) {
-            return storager.queryVideoDeviceList(page, count, true);
+            isOnline = true;
         }
-        return storager.queryVideoDeviceList(page, count, null);
+        PageInfo<Device> all;
+        if (StpAdminUtil.hasRole("primary")) {
+            all = storager.queryVideoDeviceList(page, count, domain, isOnline);
+        } else {
+            logger.info("子管理查询");
+            all = adminService.searchDevicesByAdminId(adminId, domain, isOnline, page, count);
+        }
+
+        return all;
     }
 
     /**

+ 11 - 8
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java

@@ -10,12 +10,14 @@ import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.VersionInfo;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
+import com.genersoft.iot.vmp.conf.security.saToken.SaAdminCheckRole;
 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.*;
 import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.utils.StpAdminUtil;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
 import com.genersoft.iot.vmp.vmanager.bean.ResourceInfo;
@@ -40,6 +42,7 @@ import org.slf4j.LoggerFactory;
 
 @RestController
 @RequestMapping("/api/server")
+@SaAdminCheckRole("admin")
 public class ServerController {
     private final static Logger logger =LoggerFactory.getLogger(ServerController.class);
 
@@ -238,17 +241,17 @@ public class ServerController {
     @Operation(summary = "获取配置信息")
     @Parameter(name = "type", description = "配置类型(sip, base)", required = true)
     @ResponseBody
-    public JSONObject getPushConfig(){
+    public JSONObject getPushConfig() {
         JSONObject jsonObject = new JSONObject();
-        String httpsHook = "https://"+mediaConfig.getIp() +":"+ mediaConfig.getHttpSSlPort();
-        String httpHook = "http://"+mediaConfig.getIp() +":"+ mediaConfig.getHttpPort();
+        String httpsHook = "https://" + mediaConfig.getIp() + ":" + mediaConfig.getHttpSSlPort();
+        String httpHook = "http://" + mediaConfig.getIp() + ":" + mediaConfig.getHttpPort();
         // 获取zlm的hook端口
-        jsonObject.put("httpsHook",httpsHook);
-        jsonObject.put("httpHook",httpHook);
+        jsonObject.put("httpsHook", httpsHook);
+        jsonObject.put("httpHook", httpHook);
         // 获取pushKey的值
-        int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
-        String pushKey = userService.getPushKey(currenRoleId);
-        jsonObject.put("pushKey",pushKey);
+        String adminId = StpAdminUtil.getLoginId().toString();
+        String pushKey = userService.getPushKey(adminId);
+        jsonObject.put("pushKey", pushKey);
         return jsonObject;
     }
 

+ 84 - 2
src/main/java/com/genersoft/iot/vmp/vmanager/server/sipController.java

@@ -3,7 +3,9 @@ package com.genersoft.iot.vmp.vmanager.server;
 
 import com.genersoft.iot.vmp.conf.security.saToken.SaAdminCheckRole;
 import com.genersoft.iot.vmp.gb28181.bean.SipUserConfig;
+import com.genersoft.iot.vmp.service.IAdminService;
 import com.genersoft.iot.vmp.service.ISipConfigService;
+import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
 import com.genersoft.iot.vmp.utils.StpAdminUtil;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
@@ -29,6 +31,9 @@ public class sipController {
     @Autowired
     private ISipConfigService sipConfigService;
 
+    @Autowired
+    private IAdminService adminService;
+
     @GetMapping("/search")
     @Parameter(name = "p", description = "当前页", required = true)
     @Parameter(name = "l", description = "每页查询数量", required = true)
@@ -49,6 +54,15 @@ public class sipController {
                 pageResult.getTotal());
     }
 
+    @GetMapping("/all")
+    @Operation(summary = "搜索sip列表")
+    public WVPResult<List<SipUserConfig>> getSipConfigs() {
+        logger.info("[sip配置检索] all");
+        String adminId = StpAdminUtil.getLoginId().toString();
+        List<SipUserConfig> sipConfigs = sipConfigService.getAllSipConfigsById(adminId);
+        return WVPResult.success(sipConfigs);
+    }
+
     @PostMapping("/edit")
     @Parameter(name = "id", description = "sipId", required = true)
     @Operation(summary = "编辑sip配置")
@@ -59,7 +73,7 @@ public class sipController {
         String adminId = StpAdminUtil.getLoginId().toString();
         // 判断当前用户是否有该域
         SipUserConfig oldSipConfig = sipConfigService.getSipConfigById(adminId, id);
-        if (oldSipConfig == null) {
+        if (!StpAdminUtil.hasRole("primary") && oldSipConfig == null) {
             return WVPResult.fail(ErrorCode.ERROR404, "用户无法编辑指定sip配置");
         }
         if (!sipConfigService.editSipConfig(id, sipConfig)) {
@@ -82,6 +96,62 @@ public class sipController {
         return WVPResult.success();
     }
 
+    @PostMapping("/bind")
+    @Parameter(name = "adminId", description = "adminId", required = true)
+    @Parameter(name = "sipId", description = "sipId", required = true)
+    @Operation(summary = "管理员绑定sip配置")
+    public WVPResult<String> bindConfig(
+            @RequestParam String adminId,
+            @RequestParam String sipId) {
+        logger.info("[管理员绑定sip配置] id:{}", sipId);
+        if (!StpAdminUtil.hasRole("primary")) {
+            return WVPResult.fail(ErrorCode.ERROR403);
+        }
+        AdminAccount adminAccount = adminService.getUserById(adminId);
+        if (adminAccount == null) {
+            return WVPResult.fail(ErrorCode.ERROR404, "管理员id错误, 无法找到管理员");
+        }
+        // 判断当前用户是否有该域
+        SipUserConfig oldSipConfig = sipConfigService.getSipConfigById(adminId, sipId);
+        if (oldSipConfig != null) {
+            return WVPResult.fail(ErrorCode.ERROR100, "当前用户已经拥有该配置");
+        }
+
+        if (!sipConfigService.bindSipConfig(adminId, sipId)) {
+            logger.error("[绑定sip配置失败]");
+            return WVPResult.fail(ErrorCode.ERROR100, "绑定sip配置失败");
+        }
+        return WVPResult.success();
+    }
+
+    @PostMapping("/unbind")
+    @Parameter(name = "adminId", description = "adminId", required = true)
+    @Parameter(name = "sipId", description = "sipId", required = true)
+    @Operation(summary = "解绑sip配置")
+    public WVPResult<String> unbindConfig(
+            @RequestParam String adminId,
+            @RequestParam String sipId) {
+        logger.info("[解绑sip配置] id:{}", sipId);
+        if (!StpAdminUtil.hasRole("primary")) {
+            return WVPResult.fail(ErrorCode.ERROR403);
+        }
+        AdminAccount adminAccount = adminService.getUserById(adminId);
+        if (adminAccount == null) {
+            return WVPResult.fail(ErrorCode.ERROR404, "管理员id错误, 无法找到管理员");
+        }
+        // 判断当前用户是否有该域
+        SipUserConfig oldSipConfig = sipConfigService.getSipConfigById(adminId, sipId);
+        if (oldSipConfig == null) {
+            return WVPResult.fail(ErrorCode.ERROR100, "当前用户已经拥有该配置");
+        }
+
+        if (!sipConfigService.unbindSipConfig(adminId, sipId)) {
+            logger.error("[解绑sip配置失败]");
+            return WVPResult.fail(ErrorCode.ERROR100, "解绑sip配置失败");
+        }
+        return WVPResult.success();
+    }
+
     @PostMapping("/del")
     @Parameter(name = "id", description = "sipId", required = true)
     @Operation(summary = "删除sip配置")
@@ -95,11 +165,23 @@ public class sipController {
         if (oldSipConfig == null) {
             return WVPResult.fail(ErrorCode.ERROR404, "用户无法删除指定sip配置");
         }
-        if (!sipConfigService.deleteSipConfig(id, adminId)) {
+        if (!sipConfigService.deleteSipConfig(id)) {
             logger.error("[删除sip配置失败]");
             return WVPResult.fail(ErrorCode.ERROR100, "删除sip配置失败");
         }
         return WVPResult.success();
     }
 
+
+    @GetMapping("/admins")
+    @Parameter(name = "sipId", description = "sipId", required = true)
+    @Operation(summary = "获取sip绑定的管理员信息")
+    public WVPResult<List<AdminAccount>> getSipAdmins(
+            @RequestParam String sipId) {
+        logger.info("[获取sip绑定的管理员信息] sipId:{}", sipId);
+        String adminId = StpAdminUtil.getLoginId().toString();
+        List<AdminAccount> adminAccounts = sipConfigService.getSipAdmin(sipId);
+        return WVPResult.success(adminAccounts);
+    }
+
 }

+ 0 - 75
src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java

@@ -1,75 +0,0 @@
-package com.genersoft.iot.vmp.vmanager.user;
-
-import com.genersoft.iot.vmp.conf.exception.ControllerException;
-import com.genersoft.iot.vmp.conf.security.SecurityUtils;
-import com.genersoft.iot.vmp.service.IRoleService;
-import com.genersoft.iot.vmp.storager.dao.dto.Role;
-import com.genersoft.iot.vmp.utils.DateUtil;
-import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@Tag(name  = "角色管理")
-
-@RestController
-@RequestMapping("/api/role")
-public class RoleController {
-
-    @Autowired
-    private IRoleService roleService;
-
-    @PostMapping("/add")
-    @Operation(summary = "添加角色")
-    @Parameter(name = "name", description = "角色名", required = true)
-    @Parameter(name = "authority", description = "权限(自行定义内容,目前未使用)", required = true)
-    public void add(@RequestParam String name,
-                                                  @RequestParam(required = false) String authority){
-        // 获取当前登录用户id
-        int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
-        if (currenRoleId != 1) {
-            // 只用角色id为1才可以删除和添加用户
-            throw new ControllerException(ErrorCode.ERROR403);
-        }
-
-        Role role = new Role();
-        role.setName(name);
-        role.setAuthority(authority);
-        role.setCreateTime(DateUtil.getNow());
-        role.setUpdateTime(DateUtil.getNow());
-
-        int addResult = roleService.add(role);
-        if (addResult <= 0) {
-            throw new ControllerException(ErrorCode.ERROR100);
-        }
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除角色")
-    @Parameter(name = "id", description = "用户Id", required = true)
-    public void delete(@RequestParam Integer id){
-        // 获取当前登录用户id
-        int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
-        if (currenRoleId != 1) {
-            // 只用角色id为0才可以删除和添加用户
-            throw new ControllerException(ErrorCode.ERROR403);
-        }
-        int deleteResult = roleService.delete(id);
-
-        if (deleteResult <= 0) {
-            throw new ControllerException(ErrorCode.ERROR100);
-        }
-    }
-
-    @GetMapping("/all")
-    @Operation(summary = "查询角色")
-    public List<Role> all(){
-        // 获取当前登录用户id
-        List<Role> allRoles = roleService.getAll();
-        return roleService.getAll();
-    }
-}

+ 89 - 88
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java

@@ -11,7 +11,6 @@ import com.genersoft.iot.vmp.storager.dao.dto.AdminAccount;
 import com.genersoft.iot.vmp.storager.dao.dto.Role;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import com.genersoft.iot.vmp.utils.StpAdminUtil;
-import com.genersoft.iot.vmp.utils.StpUserUtil;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 import com.github.pagehelper.PageInfo;
@@ -62,40 +61,70 @@ public class UserController {
             return WVPResult.fail(ErrorCode.ERROR100);
         }
         StpAdminUtil.login(adminAccount.getId());
+
         return WVPResult.success();
     }
 
+    @GetMapping("/logout")
+    @Operation(summary = "注销账户")
+    public WVPResult<Boolean> logout() {
+        StpAdminUtil.logout();
+        return WVPResult.success(true);
+    }
+
+    @GetMapping("/default")
+    @SaIgnore
+    @Operation(summary = "获取是否为新平台", description = "获取是否为新平台")
+    public WVPResult<Boolean> isDefault() {
+        int accountSize = userService.getUserCount();
+        if (accountSize > 0) {
+            return WVPResult.success(false);
+        }
+        return WVPResult.success(true);
+    }
+
+    // 注册管理员
+    @PostMapping("/register")
+    @SaIgnore
+    @Operation(summary = "注册管理员账户", description = "注册管理员账户")
+    @Parameter(name = "username", description = "用户名", required = true)
+    @Parameter(name = "password", description = "密码(32位md5加密)", required = true)
+    public WVPResult register(@RequestParam String username, @RequestParam String password) {
+
+        int accountSize = userService.getUserCount();
+        if (accountSize > 0) {
+            logger.warn("在已经拥有一个账户的情况下尝试注册管理员");
+            return WVPResult.fail(ErrorCode.ERROR100);
+        }
+        if (!userService.registerAdmin(username, password)) {
+            logger.warn("无法注册管理员账户");
+            return WVPResult.fail(ErrorCode.ERROR100);
+        }
+        return WVPResult.success();
+    }
 
     @PostMapping("/changePassword")
     @Operation(summary = "修改密码")
     @Parameter(name = "username", description = "用户名", required = true)
     @Parameter(name = "oldpassword", description = "旧密码(已md5加密的密码)", required = true)
     @Parameter(name = "password", description = "新密码(未md5加密的密码)", required = true)
-    public void changePassword(@RequestParam String oldPassword, @RequestParam String password){
+    public WVPResult changePassword(@RequestParam String oldPassword, @RequestParam String password) {
         logger.info("[用户管理] 修改密码");
         // 获取当前登录用户id
-        LoginUser loginUser = SecurityUtils.getUserInfo();
-        if (loginUser== null) {
-            throw new ControllerException(ErrorCode.ERROR100);
+        String adminId = StpAdminUtil.getLoginId().toString();
+        AdminAccount adminAccount = userService.getUserById(adminId);
+        String username = adminAccount.getUsername();
+        if (oldPassword != adminAccount.getPassword()) {
+            return WVPResult.fail(ErrorCode.ERROR403, "原密码错误");
         }
-        String username = loginUser.getUsername();
-        String passwordMd5 = loginUser.getPassword();
-        logger.info("[用户管理] ");
-        LoginUser user = null;
-        try {
-            user = SecurityUtils.login(username, oldPassword, authenticationManager);
-            if (user == null) {
-                throw new ControllerException(ErrorCode.ERROR100);
-            }
-//            int userId = SecurityUtils.getUserId();
-            logger.info("[用户管理] 修改密码,用户id:" + user.getId() + ",用户名:" + username);
-            boolean result = userService.changePassword(user.getId(), DigestUtils.md5DigestAsHex(password.getBytes()));
-            if (!result) {
-                throw new ControllerException(ErrorCode.ERROR100);
-            }
-        } catch (AuthenticationException e) {
-            throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
+        String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes());
+        //
+        logger.info("[用户管理] 修改密码,用户id:" + adminAccount.getId() + ",用户名:" + username);
+        boolean result = userService.changePassword(adminAccount.getId(), passwordMd5);
+        if (!result) {
+            return WVPResult.fail(ErrorCode.ERROR100, "修改密码失败");
         }
+        return WVPResult.success();
     }
 
 
@@ -103,17 +132,14 @@ public class UserController {
     @Operation(summary = "添加用户")
     @Parameter(name = "username", description = "用户名", required = true)
     @Parameter(name = "password", description = "密码(未md5加密的密码)", required = true)
-    @Parameter(name = "roleId", description = "角色ID", required = true)
-    public void add(@RequestParam String username,
-                                                 @RequestParam String password,
-                                                 @RequestParam Integer roleId) {
+    public void add(@RequestParam String username, @RequestParam String password) {
 
-        if (ObjectUtils.isEmpty(username) || ObjectUtils.isEmpty(password) || roleId == null) {
+        if (ObjectUtils.isEmpty(username) || ObjectUtils.isEmpty(password)) {
             throw new ControllerException(ErrorCode.ERROR400.getCode(), "参数不可为空");
         }
 
         // 获取当前登录用户id
-        String accountId = StpUserUtil.getLoginId().toString();
+        String accountId = StpAdminUtil.getLoginId().toString();
         logger.info("[用户管理] 添加用户,当前用户id:" + accountId);
 
         AdminAccount adminAccount = new AdminAccount();
@@ -121,12 +147,7 @@ public class UserController {
         adminAccount.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
         //新增用户的pushKey的生成规则为md5(时间戳+用户名)
         adminAccount.setPushKey(DigestUtils.md5DigestAsHex((System.currentTimeMillis() + password).getBytes()));
-        Role role = roleService.getRoleById(roleId);
 
-        if (role == null) {
-            throw new ControllerException(ErrorCode.ERROR400.getCode(), "角色不存在");
-        }
-        adminAccount.setRole(role);
         adminAccount.setCreateTime(DateUtil.getNow());
         adminAccount.setUpdateTime(DateUtil.getNow());
         int addResult = userService.addUser(adminAccount);
@@ -138,46 +159,30 @@ public class UserController {
     @DeleteMapping("/delete")
     @Operation(summary = "删除用户")
     @Parameter(name = "id", description = "用户Id", required = true)
-    public void delete(@RequestParam Integer id){
-        try {
-            // 获取当前登录用户id
-            LoginUser loginUser = SecurityUtils.getUserInfo();
-            String _username = loginUser.getUsername();
-            String _passwordMd5 = loginUser.getPassword();
-            LoginUser _user = SecurityUtils.login(_username, _passwordMd5, authenticationManager);
-            int currenRoleId = _user.getRole().getId();
-            if (currenRoleId != 1) {
-                // 只用角色id为0才可以删除和添加用户
-                throw new ControllerException(ErrorCode.ERROR400.getCode(), "用户无权限");
-            }
-            int deleteResult = userService.deleteUser(id);
-            if (deleteResult <= 0) {
-                throw new ControllerException(ErrorCode.ERROR100);
-            }
-        } catch (AuthenticationException e) {
-            throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
+    public WVPResult<String> delete(@RequestParam Integer id) {
+        // 获取当前登录用户id
+        if (!StpAdminUtil.hasRole("primary")) {
+            return WVPResult.fail(ErrorCode.ERROR403, "无权限操作");
+        }
+        int deleteResult = userService.deleteUser(id);
+        if (deleteResult <= 0) {
+            return WVPResult.fail(ErrorCode.ERROR404, "该用户不存在");
         }
+        return WVPResult.success("");
     }
 
     @GetMapping("/all")
     @Operation(summary = "查询用户")
-    public List<AdminAccount> all() {
+    public WVPResult<List<AdminAccount>> all() {
         // 获取当前登录用户id
-        return userService.getAllUsers();
-    }
-
-    public void register(String username, String password) {
-        AdminAccount adminAccount = new AdminAccount();
-        adminAccount.setUsername(username);
-        adminAccount.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
-        adminAccount.setCreateTime(DateUtil.getNow());
-        adminAccount.setUpdateTime(DateUtil.getNow());
-        int addResult = userService.addUser(adminAccount);
-        if (addResult <= 0) {
-            throw new ControllerException(ErrorCode.ERROR100);
+        if (!StpAdminUtil.hasRole("primary")) {
+            return WVPResult.fail(ErrorCode.ERROR403, "无权限操作");
         }
+        List<AdminAccount> adminAccount = userService.getAllUsers();
+        return WVPResult.success(adminAccount);
     }
 
+
     /**
      * 分页查询用户
      *
@@ -198,9 +203,9 @@ public class UserController {
     @Parameter(name = "pushKey", description = "新的pushKey", required = true)
     public WVPResult changePushKey(@RequestParam String pushKey) {
         // 获取当前登录用户id
-        String accountId = StpUserUtil.getLoginId().toString();
+        String accountId = StpAdminUtil.getLoginId().toString();
         logger.info("[用户管理] 修改pushKey,当前用户id:" + accountId);
-        int resetPushKeyResult = userService.changePushKey(Integer.parseInt(accountId), pushKey);
+        int resetPushKeyResult = userService.changePushKey(accountId, pushKey);
         if (resetPushKeyResult <= 0) {
             return WVPResult.fail(ErrorCode.ERROR100);
         }
@@ -209,31 +214,27 @@ public class UserController {
 
     @PostMapping("/changePasswordForAdmin")
     @Operation(summary = "管理员修改普通用户密码")
-    @Parameter(name = "adminId", description = "管理员id", required = true)
     @Parameter(name = "userId", description = "用户id", required = true)
     @Parameter(name = "password", description = "新密码(未md5加密的密码)", required = true)
-    public void changePasswordForAdmin(@RequestParam int userId, @RequestParam String password) {
+    public WVPResult<String> changePasswordForAdmin(@RequestParam String userId, @RequestParam String password) {
+        // 获取当前登录用户id
+
         // 获取当前登录用户id
-        try {
-            // 获取当前登录用户id
-            LoginUser loginUser = SecurityUtils.getUserInfo();
-            String _username = loginUser.getUsername();
-            String _passwordMd5 = loginUser.getPassword();
-            LoginUser _user = SecurityUtils.login(_username, _passwordMd5, authenticationManager);
-            if (_user == null) {
-                throw new ControllerException(ErrorCode.ERROR100);
-            }
-            Role role = _user.getRole();
-            if (role != null && role.getId() == 1) {
-                boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes()));
-                if (!result) {
-                    throw new ControllerException(ErrorCode.ERROR100);
-                }
-            }
-
-
-        } catch (AuthenticationException e) {
-            throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
+        String adminId = StpAdminUtil.getLoginId().toString();
+        AdminAccount adminAccount = userService.getUserById(adminId);
+        AdminAccount changeAdminAccount = userService.getUserById(userId);
+        String _passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes());
+        boolean result = false;
+        if (changeAdminAccount == null) {
+            return WVPResult.fail(ErrorCode.ERROR404, "要更改的用户不存在");
         }
+        if (StpAdminUtil.hasRole("primary")) {
+            result = userService.changePassword(userId, _passwordMd5);
+        }
+
+        if (!result) {
+            return WVPResult.fail(ErrorCode.ERROR100, "修改用户密码失败");
+        }
+        return WVPResult.success();
     }
 }

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java

@@ -67,7 +67,7 @@ public class ApiDeviceController {
             devices = storager.queryVideoDeviceList(online);
             result.put("DeviceCount", devices.size());
         }else {
-            PageInfo<Device> deviceList = storager.queryVideoDeviceList(start/limit, limit,online);
+            PageInfo<Device> deviceList = storager.queryVideoDeviceList(start / limit, limit, null, online);
             result.put("DeviceCount", deviceList.getTotal());
             devices = deviceList.getList();
         }

+ 66 - 10
web_src/src/components/DeviceList.vue

@@ -4,7 +4,20 @@
       <div class="page-title">设备列表</div>
       <div class="page-header-btn">
 
-        <el-select v-model="isOnline"
+        <el-select v-model="sipDomain"
+                   placeholder="设备域"
+                   @change="getDeviceList"
+                   size="mini"
+        >
+          <el-option
+              v-for="item in sipConfigs"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+          </el-option>
+        </el-select>
+
+        <el-select class="ml-2" v-model="isOnline"
                    placeholder="设备在线情况"
                    @change="getDeviceList"
                    size="mini"
@@ -17,12 +30,13 @@
           </el-option>
         </el-select>
 
-        <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加设备
+        <el-button class="ml-2" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">
+          添加设备
         </el-button>
 <!--        <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading"-->
 <!--                   @click="getDeviceList()"></el-button>-->
 
-        <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading"
+        <el-button class="ml-2" icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading"
                    @click="refreshDevice()"></el-button>
       </div>
     </div>
@@ -145,7 +159,9 @@ export default {
           value: 'true',
           label: '只看在线设备'
         }
-      ]
+      ],
+      sipConfigs: [],// sip 配置表
+      sipDomain: ""
     };
   },
   computed: {
@@ -171,6 +187,7 @@ export default {
   },
   methods: {
     initData: function () {
+      this.loadConfigs();
       this.getDeviceList();
     },
     currentChange: function (val) {
@@ -181,17 +198,48 @@ export default {
       this.count = val;
       this.getDeviceList();
     },
+    async loadConfigs() {
+      let url = "/api/sip/all"
+      let [err, res] = await handle(
+          this.$axios.get(url)
+      )
+      if (err || res.data.code != 0) {
+        let errStr = err ? err.message : res.data.msg
+        console.log(`[加载sip配置失败] ${errStr}`)
+        this.$message.error("加载sip配置失败");
+        return;
+      }
+      // 加载完成
+      let response = res.data;
+      let arr = []
+      arr.push({
+        value: 'all',
+        label: '全部sip配置'
+      })
+      // 解析配置表
+      response.data.forEach(sip => {
+        arr.push({
+          value: sip.sipDomain,
+          label: sip.sipDomain
+        })
+      })
+      this.sipConfigs = arr;
+    },
     getDeviceList: function () {
       this.getDeviceListLoading = true;
+      let params = {
+        page: this.currentPage,
+        count: this.count,
+        online: this.isOnline,
+      }
+      if (this.sipDomain && this.sipDomain != "all") {
+        params.domain = this.sipDomain
+      }
       this.$axios.axios({
         method: 'get',
         url: `/api/device/query/devices`,
-        params: {
-          page: this.currentPage,
-          count: this.count,
-          online: this.isOnline,
-        }
-      }).then( (res)=> {
+        params: params
+      }).then((res) => {
         if (res.data.code === 0) {
           this.total = res.data.data.total;
           this.deviceList = res.data.data.list;
@@ -378,7 +426,15 @@ export default {
   }
 };
 </script>
+<style>
+.ml-2 {
+  margin-left: 5px;
+}
 
+.mr-2 {
+  margin-left: 5px;
+}
+</style>
 <style>
 .videoList {
   display: flex;

+ 207 - 0
web_src/src/components/com/sipBind.vue

@@ -0,0 +1,207 @@
+<script>
+import handle from "@/until/handle";
+import querystring from "querystring";
+
+export default {
+  name: "sipBind",
+  props: {
+    sipDomain: {
+      default: ""
+    },
+    sipId: {
+      default: "",
+    }
+  },
+  watch: {
+    sipId: {
+      handler(newName, oldName) {
+        this.init()
+      },
+      immediate: true,
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      sipAdminsLoaded: false,
+      loadedAll: false,
+      allAdmins: [],
+      sipAdmins: [],
+      adminId: ''
+    }
+  },
+  methods: {
+    closePopHandle() {
+      this.$emit(`exitPop`)
+    },
+    init() {
+      this.loadAllAdmin()
+      this.loadSipBindAdmin()
+    },
+    async loadAllAdmin() {
+      this.loading = true;
+      let url = "/api/user/all"
+      let [err, res] = await handle(this.$axios.get(url))
+      this.loading = false;
+      if (err || res.data.code != 0) {
+        let errStr = err ? err.message : res.data.msg
+        console.log(`[获取管理员信息] ${errStr}`)
+        this.$message.error(`获取管理员信息失败 ${errStr}`);
+        return;
+      }
+      this.computeAdmins(res.data.data)
+    },
+    async loadSipBindAdmin() {
+      this.loading = true;
+      this.sipAdminsLoaded = false;
+      let url = "/api/sip/admins"
+      url += `?sipId=${this.sipId}`
+      let [err, res] = await handle(this.$axios.get(url))
+      this.loading = false;
+      if (err || res.data.code != 0) {
+        let errStr = err ? err.message : res.data.msg
+        console.log(`[获取管理员信息] ${errStr}`)
+        this.$message.error(`获取管理员信息失败 ${errStr}`);
+        return;
+      }
+      this.sipAdmins = res.data.data;
+      this.sipAdminsLoaded = true;
+      this.computeAdmins()
+    },
+    async executeBindSip() {
+      if (!this.loadedAll) {
+        console.log(`基础数据未加载`);
+        return this.$message.error(`基础数据未加载`);
+      }
+      if (!this.checkAdminId(this.adminId)) {
+        return this.$message.error(`管理员id异常,无法被添加`);
+      }
+      this.loading = true;
+      let url = "/api/sip/bind"
+      let param = {
+        sipId: this.sipId,
+        adminId: this.adminId,
+      }
+      let [err, res] = await handle(
+          this.$axios.post(url, querystring.stringify(param)))
+      this.loading = false;
+      if (err || res.data.code != 0) {
+        let errStr = err ? err.message : res.data.msg
+        console.log(`[绑定管理员信息] ${errStr}`)
+        this.$message.error(`绑定管理员信息失败 ${errStr}`);
+        return;
+      }
+      console.log('绑定管理员信息成功')
+      this.$message.success(`绑定管理员信息成功`);
+      this.closePopHandle()
+    },
+    async executeUnbindSip(adminId) {
+      if (!this.loadedAll) {
+        console.log(`基础数据未加载`);
+        return this.$message.error(`基础数据未加载`);
+      }
+      if (!this.checkSipAdminId(adminId)) {
+        return this.$message.error(`管理员id异常, 被解绑`);
+      }
+      this.loading = true;
+      let url = "/api/sip/unbind"
+      let param = {
+        sipId: this.sipId,
+        adminId: this.adminId,
+      }
+      let [err, res] = await handle(
+          this.$axios.get(url, querystring.stringify(param)))
+      this.loading = false;
+      if (err || res.data.code != 0) {
+        let errStr = err ? err.message : res.data.msg
+        console.log(`[解绑配置] ${errStr}`)
+        this.$message.error(`解绑配置失败 ${errStr}`);
+        return;
+      }
+      console.log('解绑配置成功')
+      this.$message.success(`解绑配置成功`);
+      this.closePopHandle()
+    },
+
+    computeAdmins(adminArr) {
+      console.log(`computeAdmins`)
+      console.log(this.sipAdminsLoaded)
+      console.log(adminArr)
+      if (!this.sipAdminsLoaded || !adminArr) {
+        return console.log(`数据暂时未加载完成`)
+      }
+      let allAdmins = []
+      adminArr.forEach(admin => {
+        if (!this.sipAdmins.find(val => val.id == admin.id)) {
+          allAdmins.push(admin)
+        }
+      })
+      console.log(allAdmins);
+      this.allAdmins = allAdmins;
+      this.loadedAll = true;
+    },
+    checkAdminId(adminId) {
+      if (this.allAdmins.find(val => val.id == adminId)) {
+        return true
+      }
+      return false
+    },
+    checkSipAdminId(adminId) {
+      if (this.sipAdmins.find(val => val.id == adminId)) {
+        return true
+      }
+      return false
+    },
+
+    handleUnbind(item) {
+      this.executeUnbindSip(item.id)
+    },
+    handleAdminChange() {
+
+    },
+    handleAddAdmin() {
+      this.executeBindSip()
+    }
+  }
+}
+</script>
+
+<template>
+  <div class="sips">
+    <div class="page-header">
+      <div class="page-title">sip分配</div>
+      <div class="page-header-btn">
+        <el-select v-model="adminId"
+                   placeholder="管理员"
+                   @change="handleAdminChange"
+                   size="mini"
+        >
+          <el-option
+              v-for="item in allAdmins"
+              :key="item.id"
+              :label="item.username"
+              :value="item.id">
+          </el-option>
+        </el-select>
+        <el-button
+            class="ml-2" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary"
+            @click="handleAddAdmin">绑定用户
+        </el-button>
+      </div>
+    </div>
+    <el-table :data="sipAdmins" style="width: 100%;font-size: 12px;" header-row-class-name="table-header">
+      <el-table-column prop="username" label="名称" min-width="160">
+      </el-table-column>
+      <el-table-column label="操作" min-width="450" fixed="right">
+        <template slot-scope="scope">
+          <el-button size="medium" icon="el-icon-edit" type="text" @click="handleUnbind(scope.row)">解绑</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+
+</template>
+
+<style scoped>
+
+</style>

+ 2 - 2
web_src/src/components/com/sipConfigEdit.vue

@@ -205,11 +205,11 @@ export default {
       this.loading = false;
       if (err || res.data.code != 0) {
         let errStr = err ? err.message : res.data.msg
-        console.log(`[新增sip配置] ${errStr}`)
+        console.log(`[编辑sip配置] ${errStr}`)
         this.$message.error(`编辑sip配置失败 ${errStr}`);
         return;
       }
-      this.$message.success("新增配置完成");
+      this.$message.success("编辑配置完成");
       this.closePopHandle()
     }
   }

+ 0 - 10
web_src/src/components/dialog/addUser.vue

@@ -14,16 +14,6 @@
           <el-form-item label="用户名" prop="username">
             <el-input v-model="username" autocomplete="off"></el-input>
           </el-form-item>
-          <el-form-item label="用户类型" prop="roleId" >
-            <el-select v-model="roleId"  placeholder="请选择" style="width: 100%">
-              <el-option
-                v-for="item in options"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id">
-              </el-option>
-            </el-select>
-          </el-form-item>
           <el-form-item label="密码" prop="password">
             <el-input v-model="password" autocomplete="off"></el-input>
           </el-form-item>

+ 38 - 7
web_src/src/components/setting/SipConfigs.vue

@@ -3,10 +3,11 @@ import handle from "@/until/handle";
 import syncChannelProgress from "@components/dialog/SyncChannelProgress.vue";
 import BindDevice from "@components/account_com/bindDevice.vue";
 import SipConfigEdit from "@components/com/sipConfigEdit.vue";
+import SipBind from "@components/com/sipBind.vue";
 
 export default {
   name: "sipConfigs",
-  components: {SipConfigEdit, BindDevice, syncChannelProgress},
+  components: {SipBind, SipConfigEdit, BindDevice, syncChannelProgress},
   data() {
     return {
       configs: [],
@@ -23,7 +24,10 @@ export default {
         description: "",
         enable: "",
         enableBind: "",
-      }
+      },
+      showBindPop: false,
+      sipDomain: "",
+      sipId: ""
     }
   },
   beforeMount() {
@@ -33,6 +37,7 @@ export default {
     async loadConfigs() {
       this.loading = true;
       let url = "/api/sip/search"
+      url += `?p=${this.page}&l=${this.limit}`
       let [err, res] = await handle(
           this.$axios.get(url)
       )
@@ -61,7 +66,6 @@ export default {
       this.loadConfigs()
     },
     async executeDeleteConfig(id) {
-
       if (!id) {
         console.log(`删除sip配置时出现 id 为空的情况`)
         return
@@ -107,7 +111,7 @@ export default {
       this.executeOpenConfigPop();
     },
     handleDeleteConfig(item) {
-      executeDeleteConfig(item.id);
+      this.executeDeleteConfig(item.id);
     },
     executeOpenConfigPop() {
       this.showAddConfig = true;
@@ -118,6 +122,19 @@ export default {
       this.editConfig = {};
       this.loadConfigs();
     },
+    handleOpenBind(item) {
+      this.executeOpenBindPop(item)
+    },
+    executeOpenBindPop(sip) {
+      this.sipDomain = sip.sipDomain
+      this.sipId = sip.id
+      this.showBindPop = true;
+    },
+    /** 关闭配置弹窗 */
+    executeCloseBindPop() {
+      this.showBindPop = false;
+      this.loadConfigs();
+    },
   }
 }
 
@@ -177,12 +194,12 @@ export default {
 
         <el-table-column label="操作" min-width="140" fixed="right">
           <template slot-scope="scope">
-            <el-button size="medium" icon="el-icon-edit" type="text" @click="handleOpenEditConfig(scope.row)">编辑
+            <el-button size="medium" icon="el-icon-edit" type="text" @click="handleOpenBind(scope.row)">管理员编辑
             </el-button>
             <el-divider direction="vertical"></el-divider>
-            <el-button size="medium" icon="el-icon-delete" type="text" @click="handleDeleteConfig(scope.row)"
-                       style="color: #f56c6c">删除
+            <el-button size="medium" icon="el-icon-edit" type="text" @click="handleOpenEditConfig(scope.row)">编辑
             </el-button>
+
           </template>
         </el-table-column>
       </el-table>
@@ -222,6 +239,20 @@ export default {
           @exitPop="executeCloseConfigPop"
       ></sip-config-edit>
     </el-dialog>
+
+    <el-dialog
+        :title="sipDomain"
+        :close-on-click-modal="false"
+        :visible.sync="showBindPop"
+        :destroy-on-close="true"
+        @close="executeCloseBindPop"
+    >
+      <sip-bind
+          :sip-domain="sipDomain"
+          :sip-id="sipId"
+          @close="executeCloseBindPop"
+      />
+    </el-dialog>
   </div>
 </template>