瀏覽代碼

feat: 实现web鉴权接口和用户管理接口

weijianghai 2 年之前
父節點
當前提交
0ae5d6f198
共有 39 個文件被更改,包括 1359 次插入106 次删除
  1. 18 0
      src/main/java/com/nokia/config/ApiDocConfig.java
  2. 2 0
      src/main/java/com/nokia/controller/TestController.java
  3. 7 6
      src/main/java/com/nokia/controller/UserController.java
  4. 24 5
      src/main/java/com/nokia/controller/VerificationController.java
  5. 129 0
      src/main/java/com/nokia/controller/web/WebUserController.java
  6. 45 0
      src/main/java/com/nokia/dao/OperationLogDao.java
  7. 162 18
      src/main/java/com/nokia/dao/UserDao.java
  8. 23 0
      src/main/java/com/nokia/dao/UserFunctionDao.java
  9. 14 1
      src/main/java/com/nokia/dao/UserRoleCityDao.java
  10. 39 0
      src/main/java/com/nokia/dao/VerificationLogDao.java
  11. 23 0
      src/main/java/com/nokia/pojo/OperationLog.java
  12. 1 0
      src/main/java/com/nokia/pojo/User.java
  13. 20 0
      src/main/java/com/nokia/pojo/UserFunction.java
  14. 3 1
      src/main/java/com/nokia/pojo/UserRoleCity.java
  15. 73 16
      src/main/java/com/nokia/service/AclService.java
  16. 39 0
      src/main/java/com/nokia/service/OperationLogService.java
  17. 297 43
      src/main/java/com/nokia/service/UserService.java
  18. 26 0
      src/main/java/com/nokia/vo/AddUserDto.java
  19. 29 0
      src/main/java/com/nokia/vo/AddUserRoleDto.java
  20. 1 1
      src/main/java/com/nokia/vo/AppVerificationVo.java
  21. 23 0
      src/main/java/com/nokia/vo/CopyRolesDto.java
  22. 18 0
      src/main/java/com/nokia/vo/DeleteUserDto.java
  23. 17 0
      src/main/java/com/nokia/vo/GetRoleByLoginNameDto.java
  24. 24 0
      src/main/java/com/nokia/vo/GetRoleByLoginNameVo.java
  25. 17 0
      src/main/java/com/nokia/vo/GetUserDetailDto.java
  26. 24 0
      src/main/java/com/nokia/vo/GetUserDetailRoleVo.java
  27. 34 0
      src/main/java/com/nokia/vo/GetUserDetailVo.java
  28. 22 0
      src/main/java/com/nokia/vo/ListUserDto.java
  29. 30 0
      src/main/java/com/nokia/vo/ListUserVo.java
  30. 23 0
      src/main/java/com/nokia/vo/PageDto.java
  31. 18 0
      src/main/java/com/nokia/vo/PageVo.java
  32. 4 0
      src/main/java/com/nokia/vo/TokenVo.java
  33. 17 0
      src/main/java/com/nokia/vo/TopUserDto.java
  34. 32 0
      src/main/java/com/nokia/vo/TopUserVo.java
  35. 26 0
      src/main/java/com/nokia/vo/UpdateUserDto.java
  36. 22 0
      src/main/java/com/nokia/vo/WebFunctionVo.java
  37. 18 0
      src/main/java/com/nokia/vo/WebVerificationVo.java
  38. 4 3
      src/main/resources/mapper/UserMapper.xml
  39. 11 12
      src/test/java/com/nokia/service/UserServiceTest.java

+ 18 - 0
src/main/java/com/nokia/config/ApiDocConfig.java

@@ -0,0 +1,18 @@
+package com.nokia.config;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * api文档配置
+ *
+ */
+@Configuration
+public class ApiDocConfig {
+    @Bean
+    public OpenAPI openapi() {
+        return new OpenAPI().info(new Info().title("acl_tousu").description("acl_tousu接口文档").version("1.0"));
+    }
+}

+ 2 - 0
src/main/java/com/nokia/controller/TestController.java

@@ -1,10 +1,12 @@
 package com.nokia.controller;
 
+import io.swagger.v3.oas.annotations.Hidden;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+@Hidden
 @Slf4j
 @RequestMapping("/test")
 @RestController

+ 7 - 6
src/main/java/com/nokia/controller/UserController.java

@@ -3,7 +3,6 @@ package com.nokia.controller;
 import com.nokia.common.R;
 import com.nokia.service.UserService;
 import com.nokia.vo.UserVo;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -14,17 +13,19 @@ import java.util.List;
 @RestController
 @RequestMapping("rest/api/user")
 public class UserController {
-    private final UserService userServiceImpl;
+    private final UserService userService;
 
-    @Autowired
-    public UserController(UserService userServiceImpl) {
-        this.userServiceImpl = userServiceImpl;
+    public UserController(UserService userService) {
+        this.userService = userService;
     }
 
+    /**
+     * 查询所有用户基本信息
+     */
     @PostMapping("baselist")
     @ResponseBody
     public R baseList() {
-        List<UserVo> list = userServiceImpl.baseList();
+        List<UserVo> list = userService.baseList();
         return R.ok().data(list);
     }
 }

+ 24 - 5
src/main/java/com/nokia/controller/VerificationController.java

@@ -3,25 +3,44 @@ package com.nokia.controller;
 import com.nokia.common.R;
 import com.nokia.service.AclService;
 import com.nokia.vo.TokenVo;
+import com.nokia.vo.WebVerificationVo;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.servlet.http.HttpSession;
 import javax.validation.Valid;
 
+@Tag(name = "鉴权")
 @Slf4j
 @RestController
 @RequestMapping("/api")
 public class VerificationController {
 
-    @Autowired
-    private AclService aclService;
+    private final AclService aclService;
 
+    public VerificationController(AclService aclService) {
+        this.aclService = aclService;
+    }
+
+    /**
+     * 鉴权
+     */
+    @Operation(summary = "鉴权")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "app", description = "{\"success\":true,\"code\":1,\"message\":\"成功\",\"data\":{\"userName\":\"张三\",\"list\":[{\"id\":1,\"name\":\"工单处理\",\"url\":\"url\",\"webIcon\":\"webIcon\",\"priority\":0},{\"id\":2,\"name\":\"工单答复\",\"url\":\"url\",\"webIcon\":\"webIcon\",\"priority\":0}]}}", content = @Content(schema = @Schema(implementation = WebVerificationVo.class))),
+            @ApiResponse(responseCode = "用户不存在", description = "{\"success\":false,\"code\":0,\"message\":\"用户不存在\",\"data\":null}", content = @Content)
+    })
     @PostMapping("/verification")
-    public R verifySystem(@Valid @RequestBody TokenVo tokenEntity) {
-        return aclService.verifySystem(tokenEntity);
+    public R verifySystem(@Valid @RequestBody TokenVo tokenEntity, HttpSession session) {
+        return aclService.verifySystem(tokenEntity, session);
     }
 }

+ 129 - 0
src/main/java/com/nokia/controller/web/WebUserController.java

@@ -0,0 +1,129 @@
+package com.nokia.controller.web;
+
+import com.nokia.common.R;
+import com.nokia.service.UserService;
+import com.nokia.vo.*;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpSession;
+import javax.validation.Valid;
+import java.util.List;
+
+@Tag(name = "用户")
+@RestController
+@RequestMapping("api/web/user")
+public class WebUserController {
+    private final UserService userService;
+
+    public WebUserController(UserService userService) {
+        this.userService = userService;
+    }
+
+    /**
+     * 查询top用户信息
+     */
+    @Operation(summary = "查询top用户信息")
+    @ApiResponses(value = {
+            @ApiResponse(),
+            @ApiResponse(responseCode = "没有查询到top用户信息", description = "{\"success\":false,\"code\":0,\"message\":\"没有查询到top用户信息\",\"data\":null}", content = @Content),
+            @ApiResponse(responseCode = "非本地市用户", description = "{\"success\":false,\"code\":0,\"message\":\"非本地市用户\",\"data\":null}", content = @Content),
+            @ApiResponse(responseCode = "用户已存在系统中", description = "{\"success\":false,\"code\":0,\"message\":\"用户已存在系统中\",\"data\":null}", content = @Content)
+    })
+    @PostMapping("getTopUserByLoginName")
+    public R<TopUserVo> getTopUserByLoginName(@Valid @RequestBody TopUserDto dto, HttpSession session) {
+        return userService.getTopUserByLoginName(dto, session);
+    }
+
+    /**
+     * 查询用户权限
+     */
+    @Operation(summary = "查询用户权限")
+    @ApiResponses(value = {
+            @ApiResponse(),
+            @ApiResponse(responseCode = "非本地市用户", description = "{\"success\":false,\"code\":0,\"message\":\"非本地市用户\",\"data\":null}", content = @Content),
+            @ApiResponse(responseCode = "用户不存在", description = "{\"success\":false,\"code\":0,\"message\":\"用户不存在\",\"data\":null}", content = @Content)
+    })
+    @PostMapping("getRoleByLoginName")
+    public R<List<GetRoleByLoginNameVo>> getRoleByLoginName(@Valid @RequestBody GetRoleByLoginNameDto dto, HttpSession session) {
+        return userService.getRoleByLoginName(dto, session);
+    }
+
+    /**
+     * 查询用户列表接口
+     */
+    @Operation(summary = "查询用户列表接口")
+    @PostMapping("list")
+    public R<PageVo<ListUserVo>> list(@Valid @RequestBody ListUserDto dto, HttpSession session) {
+        return userService.list(dto, session);
+    }
+
+    /**
+     * 添加用户
+     */
+    @Operation(summary = "添加用户")
+    @ApiResponses(value = {
+            @ApiResponse(),
+            @ApiResponse(responseCode = "无法添加非本地市用户", description = "{\"success\":false,\"code\":0,\"message\":\"无法添加非本地市用户\",\"data\":null}", content = @Content),
+            @ApiResponse(responseCode = "用户已存在系统中", description = "{\"success\":false,\"code\":0,\"message\":\"用户已存在系统中\",\"data\":null}", content = @Content)
+    })
+    @PostMapping("add")
+    public R<Object> add(@Valid @RequestBody AddUserDto dto, HttpSession session) {
+        return userService.add(dto, session);
+    }
+
+    /**
+     * 修改用户
+     */
+    @Operation(summary = "修改用户")
+    @ApiResponses(value = {
+            @ApiResponse(),
+            @ApiResponse(responseCode = "无法修改非本地市用户", description = "{\"success\":false,\"code\":0,\"message\":\"无法修改非本地市用户\",\"data\":null}", content = @Content)
+    })
+    @PostMapping("update")
+    public R<Object> update(@Valid @RequestBody UpdateUserDto dto, HttpSession session) {
+        return userService.update(dto, session);
+    }
+
+    /**
+     * 删除用户
+     */
+    @Operation(summary = "删除用户")
+    @ApiResponses(value = {
+            @ApiResponse(),
+            @ApiResponse(responseCode = "无法删除非本地市用户", description = "{\"success\":false,\"code\":0,\"message\":\"无法删除非本地市用户\",\"data\":null}", content = @Content)
+    })
+    @PostMapping("del")
+    public R<Object> del(@Valid @RequestBody DeleteUserDto dto, HttpSession session) {
+        return userService.del(dto, session);
+    }
+
+    /**
+     * 查询用户详情
+     */
+    @Operation(summary = "查询用户详情")
+    @PostMapping("detail")
+    public R<GetUserDetailVo> detail(@Valid @RequestBody GetUserDetailDto dto) {
+        return userService.detail(dto);
+    }
+
+    /**
+     * 批量复制权限
+     */
+    @Operation(summary = "批量复制权限")
+    @ApiResponses(value = {
+            @ApiResponse(),
+            @ApiResponse(responseCode = "无法修改非本地市用户", description = "{\"success\":false,\"code\":0,\"message\":\"无法修改非本地市用户\",\"data\":null}", content = @Content)
+    })
+    @PostMapping("copyRole")
+    public R<Object> copyRole(@Valid @RequestBody CopyRolesDto dto, HttpSession session) {
+        return userService.copyRole(dto, session);
+    }
+}

+ 45 - 0
src/main/java/com/nokia/dao/OperationLogDao.java

@@ -0,0 +1,45 @@
+package com.nokia.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nokia.pojo.OperationLog;
+import com.nokia.vo.ListOperationLogDto;
+import com.nokia.vo.ListOperationLogVo;
+import com.nokia.vo.ListVerificationLogDto;
+import com.nokia.vo.ListVerificationLogVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface OperationLogDao extends BaseMapper<OperationLog> {
+    /**
+     * 查询操作日志列表
+     *
+     */
+    @Select("<script> " +
+            "select * from sqmdb_rpt.acl_operation_log " +
+            "<where> " +
+            "    <if test='dto.operatorId'> " +
+            "         operator_id = #{dto.operatorId} " +
+            "    </if> " +
+            "    <if test='dto.operatorAccount'> " +
+            "         and operator_account like concat(#{dto.operatorAccount}, '%') " +
+            "    </if> " +
+            "    <if test='dto.operatorName'> " +
+            "         and operator_name like concat(#{dto.operatorName}, '%') " +
+            "    </if> " +
+            "    <if test='dto.operationName'> " +
+            "         and operation_name like concat('%', #{dto.operationName}, '%') " +
+            "    </if> " +
+            "    <if test='dto.startTime'> " +
+            "         and operation_time <![CDATA[ >= ]]> #{dto.startTime} " +
+            "    </if> " +
+            "    <if test='dto.endTime'> " +
+            "         and operation_time <![CDATA[ <= ]]> #{dto.endTime} " +
+            "    </if> " +
+            "</where> " +
+            "</script>")
+    List<ListOperationLogVo> listOperationLog(Page<ListOperationLogVo> page, ListOperationLogDto dto);
+}

+ 162 - 18
src/main/java/com/nokia/dao/UserDao.java

@@ -1,14 +1,14 @@
 package com.nokia.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.nokia.pojo.Role;
 import com.nokia.pojo.User;
-import com.nokia.vo.AppVerificationVO;
-import com.nokia.vo.UserVo;
+import com.nokia.vo.*;
 import com.nokia.vo.flow.FlowRoleVo;
 import com.nokia.vo.flow.FlowUserVo;
-
 import org.apache.ibatis.annotations.*;
+
 import java.util.List;
 
 @Mapper
@@ -37,7 +37,8 @@ public interface UserDao extends BaseMapper<User> {
         @Select("select a.user_id as user_id, a.login_name as login_id, a.user_name as user_name, a.phone as mobile, a.email as email,"
                         + " a.city_id as org_id, c1.area_name as org_name, a.area_id as area"
                         + " from sqmdb_rpt.acl_user a, sqmdb_rpt.acl_area c1"
-                        + " where a.city_id = c1.area_id")
+                        + " where a.city_id = c1.area_id "
+                        + "and a.deleted = 0")
         List<FlowUserVo> findToPage();
 
         /**
@@ -50,7 +51,7 @@ public interface UserDao extends BaseMapper<User> {
         @Select("select a.user_id as user_id, a.login_name as login_id, a.user_name as user_name, a.phone as mobile, a.email as email,"
                         + " a.city_id as org_id, c.area_name as org_name, a.area_id as area"
                         + " from sqmdb_rpt.acl_user a, sqmdb_rpt.acl_area c"
-                        + " where a.city_id = c.area_id and a.login_name=#{loginId}")
+                        + " where a.city_id = c.area_id and a.login_name=#{loginId} and a.deleted = 0")
         FlowUserVo getFlowUserVoByLoginId(String loginId);
 
         /**
@@ -63,13 +64,13 @@ public interface UserDao extends BaseMapper<User> {
         @Select("select a.user_id as user_id, a.login_name as login_id, a.user_name as user_name, a.phone as mobile, a.email as email,"
                         + " a.city_id as org_id, c.area_name as org_name, a.area_id as area"
                         + " from sqmdb_rpt.acl_user a, sqmdb_rpt.acl_area c"
-                        + " where a.city_id = c.area_id and user_id=#{userId}")
+                        + " where a.city_id = c.area_id and user_id=#{userId} and a.deleted = 0")
         FlowUserVo getFlowUserVoByUserId(Integer userId);
 
         @Select("select r.role_id from  sqmdb_rpt.acl_role r,  sqmdb_rpt.acl_user_role_city ur where r.role_id = ur.role_id and r.system='flow' and ur.user_id=#{userId}")
         List<Integer> findRoleIdByUserId(Integer userId);
 
-        @Select("select u.user_id from sqmdb_rpt.acl_user u,  sqmdb_rpt.acl_user_role_city ur where u.user_id = ur.user_id and ur.role_id=#{roleId}")
+        @Select("select u.user_id from sqmdb_rpt.acl_user u,  sqmdb_rpt.acl_user_role_city ur where u.user_id = ur.user_id and ur.role_id=#{roleId} and u.deleted = 0")
         List<Integer> findUserIdByRoleId(Integer roleId);
 
         @Results({
@@ -80,7 +81,7 @@ public interface UserDao extends BaseMapper<User> {
                         + "select a.user_id as user_id, a.login_name as login_id, a.user_name as user_name, a.phone as mobile, a.email as email,"
                         + " a.city_id as org_id, c.area_name as org_name, a.area_id as area"
                         + " from sqmdb_rpt.acl_user a, sqmdb_rpt.acl_area c, sqmdb_rpt.acl_user_role_city ur "
-                        + " where a.user_id = ur.user_id and a.city_id = c.area_id"
+                        + " where a.user_id = ur.user_id and a.city_id = c.area_id and a.deleted = 0"
                         + "<if test=\"loginId != null and loginId !=''\">"
                         + " and a.login_name=#{loginId} "
                         + "</if>"
@@ -97,25 +98,168 @@ public interface UserDao extends BaseMapper<User> {
 
         User getByLoginName(String loginName);
 
-        @Select("select user_id from sqmdb_rpt.acl_user au where au.login_name = #{loginName}")
-        Integer hasLoginName(String loginName);
-
         List<User> getByRoleIds(List<Integer> roleIds, List<Integer> cityIds);
 
         List<String> getPhoneListByRole(Integer roleId, Integer cityId);
 
-        @Insert("INSERT INTO sqmdb_rpt.acl_user (login_name, user_name, phone, email, city_id, area_id, province_id, org) "
-                        + " VALUES(#{loginName}, #{userName}, #{phone}, #{email}, #{cityId}, #{areaId}, #{provinceId}, #{org})")
-        int insert(User user);
+        /**
+         * 查询用户的app功能列表
+         *
+         * @param userId 用户id
+         * @param client 客户端
+         * @return {@link List}<{@link AppVerificationVo}>
+         */
+        @Select("select af.id, af.\"name\", af.app_url as url, af.app_icon, af.app_priority as priority " +
+                "from sqmdb_rpt.acl_function af " +
+                "inner join sqmdb_rpt.acl_user_function auf " +
+                "on af.id = auf.function_id " +
+                "where auf.user_id = #{userId} " +
+                "and (af.client = 0 or af.client = #{client}) " +
+                "order by af.app_priority desc")
+        List<AppVerificationVo> listAppFunctions(Integer userId, Integer client);
 
-        @Select("select af.id, af.name, af.url, af.app_icon, af.priority from sqmdb_rpt.acl_function af " +
+        /**
+         * 查询用户的web功能列表
+         *
+         * @param userId 用户id
+         * @param client 客户端
+         * @return {@link List}<{@link WebFunctionVo}>
+         */
+        @Select("select af.id, af.\"name\", af.web_url as url, af.web_icon, af.web_priority as priority " +
+                "from sqmdb_rpt.acl_function af " +
                 "inner join sqmdb_rpt.acl_user_function auf " +
                 "on af.id = auf.function_id " +
                 "where auf.user_id = #{userId} " +
                 "and (af.client = 0 or af.client = #{client}) " +
-                "order by af.priority desc")
-        List<AppVerificationVO> listUserFunctions(Integer userId, Integer client);
+                "order by af.web_priority desc")
+        List<WebFunctionVo> listWebFunctions(Integer userId, Integer client);
 
-        @Select("select * from sqmdb_rpt.acl_user order by user_id")
+        /**
+         * 查询用户列表
+         *
+         */
+        @Select("<script> " +
+                "select au.*, aa1.area_name as province_name, aa2.area_name as city_name, aa3.area_name as area_name " +
+                "from sqmdb_rpt.acl_user au " +
+                "left join sqmdb_rpt.acl_area aa1 on au.province_id = aa1.area_id " +
+                "left join sqmdb_rpt.acl_area aa2 on au.city_id = aa2.area_id " +
+                "left join sqmdb_rpt.acl_area aa3 on au.area_id = aa3.area_id " +
+                "where au.deleted = 0 " +
+                "<if test='dto.loginName'> " +
+                "     and au.login_name like concat(#{dto.loginName}, '%') " +
+                "</if> " +
+                "<if test='dto.userName'> " +
+                "     and au.user_name like concat(#{dto.userName}, '%') " +
+                "</if> " +
+                "<if test='dto.org'> " +
+                "     and au.org like concat('%', #{dto.org}, '%') " +
+                "</if> " +
+                "<if test='dto.areaId'> " +
+                "     and (au.province_id = #{dto.areaId} or au.city_id = #{dto.areaId} or au.area_id = #{dto.areaId}) " +
+                "</if> " +
+                "</script>"
+        )
+        List<ListUserVo> list(Page<ListUserVo> page, ListUserDto dto);
+
+        /**
+         * 查询top用户信息
+         *
+         * @param loginName 登录名
+         * @return {@link TopUserVo}
+         */
+        @Select("select atu.login_name, atu.org_name, atu.user_name, atu.phone, ao.province_id, ao.city_id, ao.area_id, " +
+                "aa1.area_name as province_name, aa2.area_name as city_name, aa3.area_name as area_name " +
+                "from sqmdb_rpt.acl_top_user atu " +
+                "left join acl_org ao on atu.org_id = ao.org_id " +
+                "left join sqmdb_rpt.acl_area aa1 on ao.province_id = aa1.area_id " +
+                "left join sqmdb_rpt.acl_area aa2 on ao.city_id = aa2.area_id " +
+                "left join sqmdb_rpt.acl_area aa3 on ao.area_id = aa3.area_id " +
+                "where login_name = #{loginName}")
+        TopUserVo getTopUserByLoginName(String loginName);
+
+        /**
+         * 判断账号是否存在且状态正常
+         *
+         * @param loginName 登录名
+         * @return {@link Object}
+         */
+        @Select("select 1 from sqmdb_rpt.acl_user where deleted = 0 and login_name = #{loginName}")
+        Object hasLoginName(String loginName);
+
+        /**
+         * 获取用户详细
+         *
+         * @param userId 用户id
+         * @return {@link GetUserDetailVo}
+         */
+        @Select("select au.*, au.org as org_name, aa1.area_name as province_name, aa2.area_name as city_name, aa3.area_name as area_name " +
+                "from sqmdb_rpt.acl_user au " +
+                "left join sqmdb_rpt.acl_area aa1 on au.province_id = aa1.area_id " +
+                "left join sqmdb_rpt.acl_area aa2 on au.city_id = aa2.area_id " +
+                "left join sqmdb_rpt.acl_area aa3 on au.area_id = aa3.area_id " +
+                "where au.user_id = #{userId}")
+        GetUserDetailVo getUserDetail(Integer userId);
+
+        /**
+         * 获取用户详细角色
+         *
+         * @param userId 用户id
+         * @return {@link List}<{@link GetUserDetailRoleVo}>
+         */
+        @Select("select aurc.role_id, aurc.city_id, ar.role_name, ar.\"system\", as2.system_name, aa.area_name as city_name " +
+                "from sqmdb_rpt.acl_user_role_city aurc " +
+                "inner join sqmdb_rpt.acl_role ar on aurc.role_id = ar.role_id " +
+                "inner join sqmdb_rpt.acl_area aa on aurc.city_id = aa.area_id " +
+                "inner join sqmdb_rpt.acl_system as2 on ar.\"system\" = as2.\"system\" " +
+                "where aurc.user_id = #{userId}")
+        List<GetUserDetailRoleVo> getUserDetailRole(Integer userId);
+
+        /**
+         * 获取账号角色
+         *
+         * @param loginName 登录名
+         * @return {@link List}<{@link GetRoleByLoginNameVo}>
+         */
+        @Select("select aurc.role_id, aurc.city_id, ar.role_name, ar.\"system\", as2.system_name, aa.area_name as city_name " +
+                "from sqmdb_rpt.acl_user_role_city aurc " +
+                "inner join sqmdb_rpt.acl_user au on aurc.user_id = au.user_id " +
+                "inner join sqmdb_rpt.acl_role ar on aurc.role_id = ar.role_id " +
+                "inner join sqmdb_rpt.acl_system as2 on ar.\"system\" = as2.\"system\" " +
+                "inner join sqmdb_rpt.acl_area aa on aurc.city_id = aa.area_id " +
+                "where au.login_name = #{loginName}")
+        List<GetRoleByLoginNameVo> getRoleByLoginName(String loginName);
+
+        /**
+         * 根据账号查询用户信息
+         *
+         * @param loginName 登录名
+         * @return {@link User}
+         */
+        @Select("select * from sqmdb_rpt.acl_user where login_name = #{loginName}")
+        User selectByLoginName(String loginName);
+
+        /**
+         * 存在其他地市用户
+         *
+         * @param cityId 地市id
+         * @param list   用户id列表
+         * @return {@link Object}
+         */
+        @Select("<script> " +
+                "select 1 from sqmdb_rpt.acl_user " +
+                "where city_id != #{cityId} and user_id in " +
+                "<foreach open=\"(\" close=\")\" collection=\"list\" item=\"item\" separator=\",\"> " +
+                "  #{item} " +
+                "</foreach> " +
+                "limit 1 " +
+                "</script>")
+        Object exceptCityUser(Integer cityId, List<Integer> list);
+
+        /**
+         * 查询所有用户
+         *
+         * @return {@link List}<{@link UserVo}>
+         */
+        @Select("select * from sqmdb_rpt.acl_user where deleted = 0 order by user_id")
         List<UserVo> baseList();
 }

+ 23 - 0
src/main/java/com/nokia/dao/UserFunctionDao.java

@@ -0,0 +1,23 @@
+package com.nokia.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nokia.pojo.UserFunction;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+@Mapper
+public interface UserFunctionDao extends BaseMapper<UserFunction> {
+    /**
+     * 批量插入
+     *
+     */
+    @Update("<script> " +
+            "insert into sqmdb_rpt.acl_user_function (user_id, function_id) values " +
+            "    <foreach collection=\"list\" item=\"item\" index=\"index\" separator=\",\"> " +
+            "      (#{item.userId}, #{item.functionId}) " +
+            "    </foreach> " +
+            "</script>")
+    int insertBatch(List<UserFunction> list);
+}

+ 14 - 1
src/main/java/com/nokia/dao/UserRoleCityDao.java

@@ -2,13 +2,26 @@ package com.nokia.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.nokia.pojo.UserRoleCity;
-
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
 
 @Mapper
 public interface UserRoleCityDao extends BaseMapper<UserRoleCity> {
 
     @Select("select role_id from sqmdb_rpt.acl_user_role_city where user_id = #{userId} and role_id= #{roleId} and city_id = #{cityId}")
     Integer hasRoleCity(Integer userId, Integer roleId, Integer cityId);
+
+    /**
+     * 批量插入
+     */
+    @Update("<script> " +
+            "insert into sqmdb_rpt.acl_user_role_city (user_id, role_id, city_id) values " +
+            "    <foreach collection=\"list\" item=\"item\" index=\"index\" separator=\",\"> " +
+            "      (#{item.userId}, #{item.roleId}, #{item.cityId}) " +
+            "    </foreach> " +
+            "</script>")
+    int insertBatch(List<UserRoleCity> list);
 }

+ 39 - 0
src/main/java/com/nokia/dao/VerificationLogDao.java

@@ -1,9 +1,48 @@
 package com.nokia.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.nokia.pojo.VerificationLog;
+import com.nokia.vo.ListVerificationLogDto;
+import com.nokia.vo.ListVerificationLogVo;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
 
 @Mapper
 public interface VerificationLogDao extends BaseMapper<VerificationLog> {
+    /**
+     * 查询登录日志列表
+     *
+     */
+    @Select("<script> " +
+            "select avl.login_time, avl.user_id, avl.login_name, avl.user_name, aa.area_name as city_name, as2.system_name " +
+            "from sqmdb_rpt.acl_verification_log avl " +
+            "inner join sqmdb_rpt.acl_area aa on avl.city_id = aa.area_id " +
+            "inner join sqmdb_rpt.acl_system as2 on avl.\"system\" = as2.\"system\" " +
+            "where avl.success = 1 " +
+            "<if test='dto.userId'> " +
+            "     and avl.user_id = #{dto.userId} " +
+            "</if> " +
+            "<if test='dto.cityId'> " +
+            "     and avl.city_id = #{dto.cityId} " +
+            "</if> " +
+            "<if test='dto.system'> " +
+            "     and avl.\"system\" = #{dto.system} " +
+            "</if> " +
+            "<if test='dto.loginName'> " +
+            "     and avl.login_name like concat(#{dto.loginName}, '%') " +
+            "</if> " +
+            "<if test='dto.userName'> " +
+            "     and avl.user_name like concat(#{dto.userName}, '%') " +
+            "</if> " +
+            "<if test='dto.startTime'> " +
+            "     and avl.login_time <![CDATA[ >= ]]> #{dto.startTime} " +
+            "</if> " +
+            "<if test='dto.endTime'> " +
+            "     and avl.login_time <![CDATA[ <= ]]> #{dto.endTime} " +
+            "</if> " +
+            "</script>")
+    List<ListVerificationLogVo> listVerificationLog(Page<ListVerificationLogVo> page, ListVerificationLogDto dto);
 }

+ 23 - 0
src/main/java/com/nokia/pojo/OperationLog.java

@@ -0,0 +1,23 @@
+package com.nokia.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("sqmdb_rpt.acl_operation_log")
+public class OperationLog implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private LocalDateTime operationTime;
+    private Integer operatorId;
+    private String operatorName;
+    private String operatorAccount;
+    private String operationName;
+    private String operationContent;
+}

+ 1 - 0
src/main/java/com/nokia/pojo/User.java

@@ -17,6 +17,7 @@ public class User implements Serializable {
     private String phone;
     private String email;
     private String org;
+    private Integer deleted;
     // 所属省
     private Integer provinceId;
     @TableField(exist = false)

+ 20 - 0
src/main/java/com/nokia/pojo/UserFunction.java

@@ -0,0 +1,20 @@
+package com.nokia.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/*
+ * 功能
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+@TableName("sqmdb_rpt.acl_user_function")
+public class UserFunction implements Serializable {
+    private Integer userId;
+    private Integer functionId;
+}

+ 3 - 1
src/main/java/com/nokia/pojo/UserRoleCity.java

@@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.annotation.TableName;
 
 import lombok.Data;
 
+import java.io.Serializable;
+
 @Data
 @TableName("sqmdb_rpt.acl_user_role_city")
-public class UserRoleCity {
+public class UserRoleCity implements Serializable {
 
     @TableId(type = IdType.AUTO)
     private Integer id;

+ 73 - 16
src/main/java/com/nokia/service/AclService.java

@@ -1,11 +1,14 @@
 package com.nokia.service;
 
 import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.nokia.common.R;
 import com.nokia.constants.ClientEnum;
 import com.nokia.dao.UserDao;
+import com.nokia.dao.UserRoleCityDao;
 import com.nokia.dao.VerificationLogDao;
 import com.nokia.pojo.User;
+import com.nokia.pojo.UserRoleCity;
 import com.nokia.pojo.VerificationLog;
 import com.nokia.vo.*;
 import lombok.extern.slf4j.Slf4j;
@@ -15,6 +18,7 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.servlet.http.HttpSession;
 import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.List;
@@ -42,20 +46,23 @@ public class AclService {
 
     private final RedisTemplate<String, Object> redisTemplate;
     private final VerificationLogDao verificationLogDao;
+    private final UserRoleCityDao userRoleCityDao;
 
     @Autowired
     public AclService(UserDao userDao, TopService topService, DopService dopService, WoyunweiService woyunweiService,
-                      RedisTemplate<String, Object> redisTemplate, VerificationLogDao verificationLogDao) {
+                      RedisTemplate<String, Object> redisTemplate, VerificationLogDao verificationLogDao, UserRoleCityDao userRoleCityDao) {
         this.userDao = userDao;
         this.topService = topService;
         this.dopService = dopService;
         this.woyunweiService = woyunweiService;
         this.redisTemplate = redisTemplate;
         this.verificationLogDao = verificationLogDao;
+        this.userRoleCityDao = userRoleCityDao;
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public R verifySystem(TokenVo tokenEntity) {
+    public R verifySystem(TokenVo tokenEntity, HttpSession session) {
+        log.debug("sessionId: {}", session.getId());
         Map<String, String> map = new HashMap<>();
         if (tokenEntity.getFromSystem().equalsIgnoreCase("top")) {
             map.put("redirect", topRedirectUrl);
@@ -85,9 +92,10 @@ public class AclService {
         // 从redis中查询
         userEntity = (User) redisTemplate.opsForValue().get(key);
         if (userEntity != null) {
-            log.debug("redis查询成功: {}", userEntity);
+            log.debug("redis查询成功: {}", JSON.toJSONString(userEntity));
             // 2.1 可以查到用户信息,重置redis中的用户信息,刷新到期时间
             redisTemplate.opsForValue().set(token, userEntity, timeoutSeconds, TimeUnit.SECONDS);
+            saveSession(session, userEntity, tokenEntity);
             return res(tokenEntity, userEntity, map);
         }
 
@@ -104,12 +112,14 @@ public class AclService {
         // 在前端处理,上面的问题仅影响初次点击入口的用户,不影响超时用户
         // 前端需要对入口用户做特别的处理
         userEntity = userDao.getByLoginName(tokenFlagVo.getLoginName());
-        if (userEntity == null) {
+        if (userEntity == null || userEntity.getDeleted().equals(1)) {
             return R.error().data(map).message("用户不存在");
         }
 
+        log.debug("userEntity: {}", JSON.toJSONString(userEntity));
         // 仅当用户信息不为空时,将用户信息存入redis
         redisTemplate.opsForValue().set(key, userEntity, timeoutSeconds, TimeUnit.SECONDS);
+        saveSession(session, userEntity, tokenEntity);
         R r = res(tokenEntity, userEntity, map);
         Integer success = Boolean.TRUE.equals(r.getSuccess()) ? 1 : 0;
         String res = JSON.toJSONString(r);
@@ -119,6 +129,28 @@ public class AclService {
         return r;
     }
 
+    /**
+     * 将用户信息保存到session
+     */
+    private void saveSession(HttpSession session, User userEntity, TokenVo tokenEntity) {
+        if (!"web".equals(tokenEntity.getSystem())) {
+            return;
+        }
+        QueryWrapper<UserRoleCity> wrapper = new QueryWrapper<>();
+        Map<String, Object> map = new HashMap<>();
+        map.put("user_id", userEntity.getUserId());
+        map.put("role_id", -1);
+        wrapper.allEq(map);
+        UserRoleCity userRoleCity = userRoleCityDao.selectOne(wrapper);
+        log.debug("role: {}", JSON.toJSONString(userRoleCity));
+        session.setAttribute("userinfo", userEntity);
+        session.setAttribute("role", userRoleCity);
+        session.setMaxInactiveInterval(timeoutSeconds);
+    }
+
+    /**
+     * 根据不同system返回不同结果
+     */
     private R res(TokenVo tokenEntity, User userEntity, Map<String, String> map) {
         switch (tokenEntity.getSystem().trim().toLowerCase()) {
             case "liucheng":
@@ -154,22 +186,35 @@ public class AclService {
                 LvYinVo lvYinVo = new LvYinVo(userEntity);
                 return R.ok().data(lvYinVo);
             case "app":
-                List<AppVerificationVO> vo = listUserFunctions(tokenEntity, userEntity.getUserId(),
-                        ClientEnum.APP.value);
-                return R.ok().data(vo);
+                List<AppVerificationVo> appFunctions = userDao.listAppFunctions(userEntity.getUserId(), ClientEnum.APP.value);
+                for (AppVerificationVo t : appFunctions) {
+                    t.setUrl(t.getUrl() + (t.getUrl().contains("?") ? "&" : "?")
+                            + "fromSystem=" + tokenEntity.getFromSystem() + "&token=" + tokenEntity.getToken());
+                }
+                return R.ok().data(appFunctions);
+            case "web":
+                List<WebFunctionVo> webFunctions = userDao.listWebFunctions(userEntity.getUserId(), ClientEnum.WEB.value);
+                for (WebFunctionVo t : webFunctions) {
+                    t.setUrl(t.getUrl() + (t.getUrl().contains("?") ? "&" : "?")
+                            + "&fromSystem=" + tokenEntity.getFromSystem() + "&token=" + tokenEntity.getToken());
+                }
+                WebVerificationVo webVo = new WebVerificationVo();
+                webVo.setUserName(userEntity.getUserName());
+                webVo.setList(webFunctions);
+                return R.ok().data(webVo);
             default:
-                return R.error().message("当前允许的system为: liucheng/fenxi/daping/yuce/heidianku/volte_t2/luyin/app");
+                return R.error().message("当前允许的system为: liucheng/fenxi/daping/yuce/heidianku/volte_t2/luyin/app/web");
         }
     }
 
-    private List<AppVerificationVO> listUserFunctions(TokenVo tokenEntity, Integer userId, Integer client) {
-        List<AppVerificationVO> list = userDao.listUserFunctions(userId, client);
-        for (AppVerificationVO t : list) {
-            t.setUrl(t.getUrl() + "&fromSystem=" + tokenEntity.getFromSystem() + "&token=" + tokenEntity.getToken());
-        }
-        return list;
-    }
-
+    /**
+     * 记录登录日志
+     *
+     * @param tokenEntity 令牌实体
+     * @param userEntity  用户实体
+     * @param success     是否成功
+     * @param res         返回结果
+     */
     private void logVerification(TokenVo tokenEntity, User userEntity, Integer success, String res) {
         VerificationLog verificationLog = new VerificationLog();
         verificationLog.setUserId(userEntity.getUserId());
@@ -183,6 +228,12 @@ public class AclService {
         verificationLogDao.insert(verificationLog);
     }
 
+    /**
+     * 获取鉴权结果
+     *
+     * @param token      令牌
+     * @param fromSystem 从系统
+     */
     private TokenFlagVo getVerifyResult(String token, String fromSystem) {
         if (fromSystem.trim().equalsIgnoreCase("dop")) {
             return dopService.dopReturn(token);
@@ -197,6 +248,12 @@ public class AclService {
         return null;
     }
 
+    /**
+     * 测试令牌
+     *
+     * @param token 令牌
+     * @return {@link TokenFlagVo}
+     */
     private TokenFlagVo testToken(String token) {
         String login_name = token.trim().toLowerCase();
         login_name = login_name.replace("test_token_", "test_");

+ 39 - 0
src/main/java/com/nokia/service/OperationLogService.java

@@ -0,0 +1,39 @@
+package com.nokia.service;
+
+import com.nokia.dao.OperationLogDao;
+import com.nokia.pojo.OperationLog;
+import com.nokia.pojo.User;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpSession;
+import java.time.LocalDateTime;
+
+@Service
+public class OperationLogService {
+    private final OperationLogDao operationLogDao;
+
+    public OperationLogService(OperationLogDao operationLogDao) {
+        this.operationLogDao = operationLogDao;
+    }
+
+    /**
+     * 记录操作日志
+     *
+     * @param session          会话
+     * @param operationName    操作名称
+     * @param operationContent 操作内容
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void logOperation(HttpSession session, String operationName, String operationContent) {
+        User userinfo = (User) session.getAttribute("userinfo");
+        OperationLog operationLog = new OperationLog();
+        operationLog.setOperationTime(LocalDateTime.now());
+        operationLog.setOperatorId(userinfo.getUserId());
+        operationLog.setOperatorName(userinfo.getUserName());
+        operationLog.setOperatorAccount(userinfo.getLoginName());
+        operationLog.setOperationName(operationName);
+        operationLog.setOperationContent(operationContent);
+        operationLogDao.insert(operationLog);
+    }
+}

+ 297 - 43
src/main/java/com/nokia/service/UserService.java

@@ -1,80 +1,334 @@
 package com.nokia.service;
 
-import com.nokia.vo.UserVo;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nokia.common.R;
 import com.nokia.dao.UserDao;
+import com.nokia.dao.UserFunctionDao;
 import com.nokia.dao.UserRoleCityDao;
-import com.nokia.pojo.Area;
-import com.nokia.pojo.Role;
 import com.nokia.pojo.User;
+import com.nokia.pojo.UserFunction;
 import com.nokia.pojo.UserRoleCity;
+import com.nokia.vo.*;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
+import javax.servlet.http.HttpSession;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 @Service
-public class UserService extends ServiceImpl<UserDao, User> {
+public class UserService {
 
     private final UserDao userDao;
     private final UserRoleCityDao userRoleCityDao;
+    private final UserFunctionDao userFunctionDao;
+    private final OperationLogService operationLogService;
 
-    @Autowired
-    public UserService(UserDao userDao, UserRoleCityDao userRoleCityDao) {
+    public UserService(UserDao userDao, UserRoleCityDao userRoleCityDao, UserFunctionDao userFunctionDao, OperationLogService operationLogService) {
         this.userDao = userDao;
         this.userRoleCityDao = userRoleCityDao;
+        this.userFunctionDao = userFunctionDao;
+        this.operationLogService = operationLogService;
     }
 
-    /**
-     * 指定的登陆名是否已存在
-     */
-    public boolean hasLoginName(String loginName) {
-        return null != userDao.hasLoginName(loginName);
+    public List<UserVo> baseList() {
+        return userDao.baseList();
+    }
+
+    public R<TopUserVo> getTopUserByLoginName(TopUserDto dto, HttpSession session) {
+        if (hasLoginName(dto.getLoginName())) {
+            return R.error("用户已存在系统中");
+        }
+        TopUserVo vo = userDao.getTopUserByLoginName(dto.getLoginName());
+        if (vo == null) {
+            return R.error("没有查询到top用户信息");
+        }
+        UserRoleCity role = getUserRoleCity(session);
+        if (role.getCityId() != -1 && !role.getCityId().equals(vo.getCityId())) {
+            return R.error("非本地市用户");
+        }
+        return R.ok(vo);
+    }
+
+    public R<List<GetRoleByLoginNameVo>> getRoleByLoginName(GetRoleByLoginNameDto dto, HttpSession session) {
+        User user = userDao.selectByLoginName(dto.getLoginName());
+        if (user == null || user.getDeleted().equals(1)) {
+            return R.error("账号不存在");
+        }
+        UserRoleCity role = getUserRoleCity(session);
+        if (role.getCityId() != -1 && !role.getCityId().equals(user.getCityId())) {
+            return R.error("非本地市用户");
+        }
+        List<GetRoleByLoginNameVo> vo = userDao.getRoleByLoginName(dto.getLoginName());
+        return R.ok(vo);
+    }
+
+    public R<PageVo<ListUserVo>> list(ListUserDto dto, HttpSession session) {
+        // 默认归属地市
+        if (dto.getAreaId() == null) {
+            User userinfo = getUserInfo(session);
+            dto.setAreaId(userinfo.getCityId());
+        }
+        PageVo<ListUserVo> vo = new PageVo<>();
+        Page<ListUserVo> page = new Page<>(dto.getCurrent(), dto.getPageSize());
+        page.addOrder(OrderItem.asc("au.city_id"));
+        List<ListUserVo> list = userDao.list(page, dto);
+        vo.setList(list);
+        vo.setTotal(page.getTotal());
+        return R.ok(vo);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public R<Object> add(AddUserDto dto, HttpSession session) {
+        User user = userDao.selectByLoginName(dto.getLoginName());
+        if (user != null && user.getDeleted().equals(0)) {
+            return R.error("用户已存在系统中");
+        }
+        TopUserVo topUser = userDao.getTopUserByLoginName(dto.getLoginName());
+        if (topUser == null) {
+            return R.error("没有查询到top用户信息");
+        }
+        if (topUser.getCityId() == null) {
+            topUser.setCityId(topUser.getProvinceId());
+        }
+        UserRoleCity role = getUserRoleCity(session);
+        if (role.getCityId() != -1 && !role.getCityId().equals(topUser.getCityId())) {
+            return R.error("无法添加非本地市用户");
+        }
+        if (user == null) {
+            user = new User();
+        }
+        user.setLoginName(topUser.getLoginName());
+        user.setUserName(topUser.getUserName());
+        user.setPhone(topUser.getPhone());
+        user.setEmail(dto.getEmail());
+        user.setOrg(topUser.getOrgName());
+        user.setDeleted(0);
+        user.setProvinceId(topUser.getProvinceId());
+        user.setCityId(topUser.getCityId());
+        user.setAreaId(topUser.getAreaId());
+        // 插入新用户
+        if (user.getUserId() == null) {
+            userDao.insert(user);
+        } else {
+            // 修改已删除用户信息
+            userDao.updateById(user);
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append("添加用户 ").append(topUser.getLoginName()).append(";")
+                .append("用户名:").append(topUser.getUserName()).append(",")
+                .append("手机号:").append(topUser.getPhone()).append(",")
+                .append("邮箱:").append(dto.getEmail()).append(",")
+                .append("部门:").append(topUser.getOrgName()).append(",")
+                .append("省份:").append(topUser.getProvinceName()).append(",")
+                .append("地市:").append(topUser.getCityName()).append(",")
+                .append("区县:").append(topUser.getAreaName()).append(";");
+        if (!CollectionUtils.isEmpty(dto.getRoles())) {
+            int userId = user.getUserId();
+            List<UserRoleCity> userRoleCities = new ArrayList<>();
+            Set<Integer> functionIds = new HashSet<>();
+            sb.append("角色:");
+            for (AddUserRoleDto t : dto.getRoles()) {
+                sb.append(t.getRoleName()).append("-").append(t.getCityName()).append(",");
+                UserRoleCity userRoleCity = new UserRoleCity();
+                userRoleCity.setUserId(userId);
+                userRoleCity.setRoleId(t.getRoleId());
+                userRoleCity.setCityId(t.getCityId());
+                userRoleCities.add(userRoleCity);
+                if (t.getFunctionId() != null) {
+                    functionIds.add(t.getFunctionId());
+                }
+            }
+            userRoleCityDao.insertBatch(userRoleCities);
+            if (!CollectionUtils.isEmpty(functionIds)) {
+                List<UserFunction> userFunctions = functionIds.stream().map(t -> new UserFunction(userId, t))
+                        .collect(Collectors.toList());
+                userFunctionDao.insertBatch(userFunctions);
+            }
+        }
+        // 记录日志
+        operationLogService.logOperation(session, "添加用户", sb.toString());
+        return R.ok();
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public R<Object> update(UpdateUserDto dto, HttpSession session) {
+        User user = userDao.selectById(dto.getUserId());
+        UserRoleCity role = getUserRoleCity(session);
+        if (role.getCityId() != -1 && !role.getCityId().equals(user.getCityId())) {
+            return R.error("无法修改非本地市用户");
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append("修改用户 ").append(user.getLoginName()).append(";");
+        if (StringUtils.hasText(dto.getEmail()) && !dto.getEmail().equals(user.getEmail())) {
+            sb.append("邮箱旧值:").append(user.getEmail()).append(",")
+                    .append("邮箱新值:").append(dto.getEmail()).append(";");
+            user.setEmail(dto.getEmail());
+            userDao.updateById(user);
+        }
+        if (!CollectionUtils.isEmpty(dto.getRoles())) {
+            int userId = user.getUserId();
+            List<GetUserDetailRoleVo> oldRoles = userDao.getUserDetailRole(userId);
+            sb.append("角色旧值:");
+            for (GetUserDetailRoleVo t : oldRoles) {
+                sb.append(t.getRoleName()).append("-").append(t.getCityName()).append(",");
+            }
+            List<UserRoleCity> userRoleCities = new ArrayList<>();
+            Set<Integer> functionIds = new HashSet<>();
+            sb.append(";角色新值:");
+            for (AddUserRoleDto t : dto.getRoles()) {
+                sb.append(t.getRoleName()).append("-").append(t.getCityName()).append(",");
+                UserRoleCity userRoleCity = new UserRoleCity();
+                userRoleCity.setUserId(user.getUserId());
+                userRoleCity.setRoleId(t.getRoleId());
+                userRoleCity.setCityId(t.getCityId());
+                userRoleCities.add(userRoleCity);
+                if (t.getFunctionId() != null) {
+                    functionIds.add(t.getFunctionId());
+                }
+            }
+            UpdateWrapper<UserRoleCity> userRoleCityUpdateWrapper = new UpdateWrapper<>();
+            userRoleCityUpdateWrapper.eq("user_id", dto.getUserId());
+            userRoleCityDao.delete(userRoleCityUpdateWrapper);
+            userRoleCityDao.insertBatch(userRoleCities);
+            if (!CollectionUtils.isEmpty(functionIds)) {
+                UpdateWrapper<UserFunction> userFunctionUpdateWrapper = new UpdateWrapper<>();
+                userFunctionUpdateWrapper.eq("user_id", dto.getUserId());
+                userFunctionDao.delete(userFunctionUpdateWrapper);
+                List<UserFunction> userFunctions = functionIds.stream().map(t -> new UserFunction(userId, t))
+                        .collect(Collectors.toList());
+                userFunctionDao.insertBatch(userFunctions);
+            }
+        }
+        // 记录日志
+        operationLogService.logOperation(session, "修改用户", sb.toString());
+        return R.ok();
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public R<Object> del(DeleteUserDto dto, HttpSession session) {
+        UserRoleCity role = getUserRoleCity(session);
+        if (role.getCityId() != -1 && userDao.exceptCityUser(role.getCityId(), dto.getUserIds()) != null) {
+            return R.error("无法删除非本地市用户");
+        }
+        User user = new User();
+        user.setDeleted(1);
+        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
+        wrapper.in("user_id", dto.getUserIds());
+        userDao.update(user, wrapper);
+        deleteUserRoleCityByUserIds(dto.getUserIds());
+        deleteUserFunctionByUserIds(dto.getUserIds());
+        StringBuilder sb = new StringBuilder();
+        List<User> users = userDao.selectBatchIds(dto.getUserIds());
+        String loginNames = users.stream().map(User::getLoginName).collect(Collectors.joining("、"));
+        sb.append("删除用户 ").append(loginNames);
+        // 记录日志
+        operationLogService.logOperation(session, "删除用户", sb.toString());
+        return R.ok();
+    }
+
+    public R<GetUserDetailVo> detail(GetUserDetailDto dto) {
+        GetUserDetailVo vo = userDao.getUserDetail(dto.getUserId());
+        List<GetUserDetailRoleVo> roles = userDao.getUserDetailRole(dto.getUserId());
+        vo.setRoles(roles);
+        return R.ok(vo);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public R<Object> copyRole(CopyRolesDto dto, HttpSession session) {
+        UserRoleCity role = getUserRoleCity(session);
+        if (role.getCityId() != -1 && userDao.exceptCityUser(role.getCityId(), dto.getUserIds()) != null) {
+            return R.error("无法修改非本地市用户");
+        }
+        StringBuilder sb = new StringBuilder();
+        List<User> users = userDao.selectBatchIds(dto.getUserIds());
+        String loginNames = users.stream().map(User::getLoginName).collect(Collectors.joining("、"));
+        sb.append("批量复制权限给 ").append(loginNames).append(";权限:");
+        List<UserRoleCity> userRoleCities = new ArrayList<>();
+        List<UserFunction> userFunctions = new ArrayList<>();
+        for (AddUserRoleDto t : dto.getRoles()) {
+            sb.append(t.getRoleName()).append("-").append(t.getCityName()).append(",");
+            for (Integer userId : dto.getUserIds()) {
+                UserRoleCity userRoleCity = new UserRoleCity();
+                userRoleCity.setUserId(userId);
+                userRoleCity.setRoleId(t.getRoleId());
+                userRoleCity.setCityId(t.getCityId());
+                userRoleCities.add(userRoleCity);
+                if (t.getFunctionId() != null) {
+                    UserFunction userFunction = new UserFunction();
+                    userFunction.setUserId(userId);
+                    userFunction.setFunctionId(t.getFunctionId());
+                    userFunctions.add(userFunction);
+                }
+            }
+        }
+        deleteUserRoleCityByUserIds(dto.getUserIds());
+        userRoleCityDao.insertBatch(userRoleCities);
+        if (!CollectionUtils.isEmpty(userFunctions)) {
+            deleteUserFunctionByUserIds(dto.getUserIds());
+            userFunctionDao.insertBatch(userFunctions);
+        }
+        // 记录日志
+        operationLogService.logOperation(session, "批量复制权限", sb.toString());
+        return R.ok();
     }
 
     /**
-     * 用户是否存在某个权限
+     * 获取用户信息
+     *
+     * @param session 会话
+     * @return {@link User}
      */
-    public boolean hasRoleCity(User user, Role role, Area city) {
-        return null != userRoleCityDao.hasRoleCity(user.getUserId(), role.getRoleId(), city.getAreaId());
+    public User getUserInfo(HttpSession session) {
+        return  (User) session.getAttribute("userinfo");
     }
 
     /**
-     * 添加用户
+     * 得到用户角色城市
+     *
+     * @param session 会话
+     * @return {@link UserRoleCity}
      */
-    @Transactional
-    public String add(User user) {
-        User query = new User();
-        query.setLoginName(user.getLoginName());
-        User one = baseMapper.selectOne(Wrappers.query(query));
-        if (one != null) {
-            return "loginName: " + user.getLoginName() + " 已存在";
-        } else {
-            user.setCityId(user.getCity().getAreaId());
-            baseMapper.insert(user);
-        }
-        return "ok";
+    public UserRoleCity getUserRoleCity(HttpSession session) {
+        return (UserRoleCity) session.getAttribute("role");
     }
 
-    /*
-     * 添加权限
+    /**
+     * 登录名存在
+     *
+     * @param loginName 登录名
+     * @return boolean
      */
-    public void addUserRoleCity(UserRoleCity userRoleCity) {
-        userRoleCityDao.insert(userRoleCity);
+    private boolean hasLoginName(String loginName) {
+        return userDao.hasLoginName(loginName) != null;
     }
 
     /**
-     * 通过用户的登录名获取用户完整信息
+     * 通过用户id删除用户功能
+     *
+     * @param list 列表
      */
-    public User getByLoginName(String loginName) {
-        return userDao.getByLoginName(loginName);
+    private void deleteUserFunctionByUserIds(List<Integer> list) {
+        UpdateWrapper<UserFunction> wrapper = new UpdateWrapper<>();
+        wrapper.in("user_id", list);
+        userFunctionDao.delete(wrapper);
     }
 
-    public List<UserVo> baseList() {
-        return userDao.baseList();
+    /**
+     * 通过用户id删除用户角色城市
+     *
+     * @param list 列表
+     */
+    private void deleteUserRoleCityByUserIds(List<Integer> list) {
+        UpdateWrapper<UserRoleCity> wrapper = new UpdateWrapper<>();
+        wrapper.in("user_id", list);
+        userRoleCityDao.delete(wrapper);
     }
-
 }

+ 26 - 0
src/main/java/com/nokia/vo/AddUserDto.java

@@ -0,0 +1,26 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class AddUserDto {
+    @Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "zhangsan")
+    @NotBlank(message = "loginName不能为空")
+    private String loginName;
+    @Schema(description = "邮箱")
+    @Email(message = "邮箱格式错误")
+    private String email;
+    @Schema(description = "角色列表")
+    @Valid
+    private List<AddUserRoleDto> roles;
+}

+ 29 - 0
src/main/java/com/nokia/vo/AddUserRoleDto.java

@@ -0,0 +1,29 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class AddUserRoleDto {
+    @Schema(description = "角色id", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "roleId不能为空")
+    private Integer roleId;
+    @Schema(description = "地市id", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "cityId不能为空")
+    private Integer cityId;
+    @Schema(description = "角色名称", example = "工单查询", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "roleName不能为空")
+    private String roleName;
+    @Schema(description = "地市名称", example = "石家庄市", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "cityName不能为空")
+    private String cityName;
+    @Schema(description = "功能id")
+    private Integer functionId;
+}

+ 1 - 1
src/main/java/com/nokia/vo/AppVerificationVO.java → src/main/java/com/nokia/vo/AppVerificationVo.java

@@ -7,7 +7,7 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 @NoArgsConstructor
 @Data
-public class AppVerificationVO {
+public class AppVerificationVo {
     private Integer id;
     private String name;
     private String url;

+ 23 - 0
src/main/java/com/nokia/vo/CopyRolesDto.java

@@ -0,0 +1,23 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class CopyRolesDto {
+    @Schema(description = "用户id列表", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "userIds不能为空")
+    private List<Integer> userIds;
+    @Schema(description = "角色列表", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "roles不能为空")
+    @Valid
+    private List<AddUserRoleDto> roles;
+}

+ 18 - 0
src/main/java/com/nokia/vo/DeleteUserDto.java

@@ -0,0 +1,18 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class DeleteUserDto {
+    @Schema(description = "用户id列表", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "userIds不能为空")
+    private List<Integer> userIds;
+}

+ 17 - 0
src/main/java/com/nokia/vo/GetRoleByLoginNameDto.java

@@ -0,0 +1,17 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class GetRoleByLoginNameDto {
+    @Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "zhangsan")
+    @NotBlank(message = "loginName不能为空")
+    private String loginName;
+}

+ 24 - 0
src/main/java/com/nokia/vo/GetRoleByLoginNameVo.java

@@ -0,0 +1,24 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class GetRoleByLoginNameVo {
+    @Schema(description = "角色id")
+    private Integer roleId;
+    @Schema(description = "角色名称", example = "工单查询")
+    private String roleName;
+    @Schema(description = "系统id", example = "flow")
+    private String system;
+    @Schema(description = "系统名称", example = "流程")
+    private String systemName;
+    @Schema(description = "地区id")
+    private Integer cityId;
+    @Schema(description = "地市名称", example = "石家庄市")
+    private String cityName;
+}

+ 17 - 0
src/main/java/com/nokia/vo/GetUserDetailDto.java

@@ -0,0 +1,17 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class GetUserDetailDto {
+    @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "userId不能为空")
+    private Integer userId;
+}

+ 24 - 0
src/main/java/com/nokia/vo/GetUserDetailRoleVo.java

@@ -0,0 +1,24 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class GetUserDetailRoleVo {
+    @Schema(description = "角色id")
+    private Integer roleId;
+    @Schema(description = "地区id")
+    private Integer cityId;
+    @Schema(description = "角色名称", example = "工单查询")
+    private String roleName;
+    @Schema(description = "地市名称", example = "石家庄市")
+    private String cityName;
+    @Schema(description = "系统id", example = "flow")
+    private String system;
+    @Schema(description = "系统名称", example = "流程")
+    private String systemName;
+}

+ 34 - 0
src/main/java/com/nokia/vo/GetUserDetailVo.java

@@ -0,0 +1,34 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class GetUserDetailVo {
+    @Schema(description = "用户id")
+    private Integer userId;
+    @Schema(description = "账号", example = "zhangsan")
+    private String loginName;
+    @Schema(description = "用户名", example = "张三")
+    private String userName;
+    @Schema(description = "手机号", example = "12345678901")
+    private String phone;
+    @Schema(description = "组织", example = "河北省分公司云网运营中心")
+    private String orgName;
+    @Schema(description = "省份名称", example = "河北省")
+    private String provinceName;
+    @Schema(description = "地市名称", example = "石家庄市")
+    private String cityName;
+    @Schema(description = "区县名称", example = "长安区")
+    private String areaName;
+    @Schema(description = "邮箱")
+    private String email;
+    @Schema(description = "角色列表")
+    private List<GetUserDetailRoleVo> roles;
+}

+ 22 - 0
src/main/java/com/nokia/vo/ListUserDto.java

@@ -0,0 +1,22 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ListUserDto extends PageDto {
+    @Schema(description = "账号", example = "zhangsan")
+    private String loginName;
+    @Schema(description = "用户名", example = "张三")
+    private String userName;
+    @Schema(description = "组织", example = "河北")
+    private String org;
+    @Schema(description = "地区id", example = "-1")
+    private Integer areaId;
+}

+ 30 - 0
src/main/java/com/nokia/vo/ListUserVo.java

@@ -0,0 +1,30 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class ListUserVo {
+    @Schema(description = "用户id")
+    private Integer userId;
+    @Schema(description = "账号", example = "zhangsan")
+    private String loginName;
+    @Schema(description = "用户名", example = "张三")
+    private String userName;
+    @Schema(description = "手机号", example = "12345678901")
+    private String phone;
+    @Schema(description = "邮箱")
+    private String email;
+    @Schema(description = "河北省分公司云网运营中心")
+    private String org;
+    @Schema(description = "省份名称", example = "河北省")
+    private String provinceName;
+    @Schema(description = "地市名称", example = "石家庄市")
+    private String cityName;
+    @Schema(description = "区县名称", example = "长安区")
+    private String areaName;
+}

+ 23 - 0
src/main/java/com/nokia/vo/PageDto.java

@@ -0,0 +1,23 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Range;
+
+import javax.validation.constraints.NotNull;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class PageDto {
+    @Schema(description = "页码,最小值1", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "页码不能为空")
+    @Range(min = 1, message = "页码错误")
+    private Integer current;
+    @Schema(description = "每页个数,最小值1", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @NotNull(message = "每页个数不能为空")
+    @Range(min = 1, message = "每页个数错误")
+    private Integer pageSize;
+}

+ 18 - 0
src/main/java/com/nokia/vo/PageVo.java

@@ -0,0 +1,18 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class PageVo<T> {
+    @Schema(description = "数据总条数", example = "1000")
+    private Long total;
+    @Schema(description = "数据列表")
+    private List<T> list;
+}

+ 4 - 0
src/main/java/com/nokia/vo/TokenVo.java

@@ -1,5 +1,6 @@
 package com.nokia.vo;
 
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
@@ -10,10 +11,13 @@ import java.io.Serializable;
  */
 @Data
 public class TokenVo implements Serializable {
+    @Schema(description = "token", requiredMode = Schema.RequiredMode.REQUIRED, example = "test_token_hebei")
     @NotBlank(message = "token不能为空")
     private String token;
+    @Schema(description = "system", requiredMode = Schema.RequiredMode.REQUIRED, example = "web")
     @NotBlank(message = "system不能为空")
     private String system;
+    @Schema(description = "fromSystem", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
     @NotBlank(message = "fromSystem不能为空")
     private String fromSystem;
 }

+ 17 - 0
src/main/java/com/nokia/vo/TopUserDto.java

@@ -0,0 +1,17 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class TopUserDto {
+    @Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "zhangsan")
+    @NotBlank(message = "loginName不能为空")
+    private String loginName;
+}

+ 32 - 0
src/main/java/com/nokia/vo/TopUserVo.java

@@ -0,0 +1,32 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class TopUserVo {
+    @Schema(description = "账号", example = "zhangsan")
+    private String loginName;
+    @Schema(description = "用户名", example = "张三")
+    private String userName;
+    @Schema(description = "手机号", example = "12345678901")
+    private String phone;
+    @Schema(description = "组织", example = "河北省分公司云网运营中心")
+    private String orgName;
+    @Schema(description = "省份id")
+    private Integer provinceId;
+    @Schema(description = "地市id")
+    private Integer cityId;
+    @Schema(description = "区县id")
+    private Integer areaId;
+    @Schema(description = "省份名称", example = "河北省")
+    private String provinceName;
+    @Schema(description = "地市名称", example = "石家庄市")
+    private String cityName;
+    @Schema(description = "区县名称", example = "长安区")
+    private String areaName;
+}

+ 26 - 0
src/main/java/com/nokia/vo/UpdateUserDto.java

@@ -0,0 +1,26 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class UpdateUserDto {
+    @Schema(description = "邮箱")
+    @Email(message = "邮箱格式错误")
+    private String email;
+    @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "userId不能为空")
+    private Integer userId;
+    @Schema(description = "角色列表")
+    @Valid
+    private List<AddUserRoleDto> roles;
+}

+ 22 - 0
src/main/java/com/nokia/vo/WebFunctionVo.java

@@ -0,0 +1,22 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class WebFunctionVo {
+    @Schema(description = "功能id")
+    private Integer id;
+    @Schema(description = "功能名称")
+    private String name;
+    @Schema(description = "web链接")
+    private String url;
+    @Schema(description = "web图标")
+    private String webIcon;
+    @Schema(description = "显示优先级")
+    private Integer priority;
+}

+ 18 - 0
src/main/java/com/nokia/vo/WebVerificationVo.java

@@ -0,0 +1,18 @@
+package com.nokia.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class WebVerificationVo {
+    @Schema(description = "用户名", example = "张三")
+    private String userName;
+    @Schema(description = "入口列表")
+    private List<WebFunctionVo> list;
+}

+ 4 - 3
src/main/resources/mapper/UserMapper.xml

@@ -10,6 +10,7 @@
         <result column="province_id" property="provinceId" />
         <result column="city_id" property="cityId" />
         <result column="area_id" property="areaId" />
+        <result column="deleted" property="deleted" />
         <association column="province_id" property="province">
             <id column="province_id" property="areaId"></id>
             <result column="province_Name" property="areaName" />
@@ -47,7 +48,7 @@
 
     <select id="getByLoginName" resultMap="UserResultMap">
         select tmp.*, ac4.area_name, ac4.parent_id as area_parent_id
-            from ( select au.user_id, au.login_name, au.user_name, au.phone, au.email, au.province_id,
+            from ( select au.user_id, au.login_name, au.user_name, au.phone, au.email, au.province_id, au.deleted,
                 ac.area_name as province_name, au.city_id, ac2.area_name as city_name, ac2.parent_id as city_parent_id,
                 ac2.type_code, au.area_id, ar.role_id, ar.role_name, ar."system",
                 aurc.city_id as role_city_id, ac3.area_name as role_area_name
@@ -61,7 +62,7 @@
                 and aurc.city_id = ac3.area_id ) tmp
             left join sqmdb_rpt.acl_area ac4
             on tmp.area_id = ac4.area_id
-        where 1=1
+        where tmp.deleted = 0
             and tmp.login_name = #{loginName}
     </select>
 
@@ -78,7 +79,7 @@
             where
                 au.user_id = aurc.user_id and ar.role_id = aurc.role_id
                 and au.province_id = ac.area_id and au.city_id = ac2.area_id
-                and aurc.city_id = ac3.area_id ) tmp
+                and aurc.city_id = ac3.area_id and au.deleted = 0 ) tmp
             left join sqmdb_rpt.acl_area ac4
             on tmp.area_id = ac4.area_id
         where tmp.user_id != 1

+ 11 - 12
src/test/java/com/nokia/service/UserServiceTest.java

@@ -1,21 +1,20 @@
 package com.nokia.service;
 
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.data.redis.core.RedisTemplate;
-
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.nokia.dao.UserDao;
 import com.nokia.dao.UserRoleCityDao;
 import com.nokia.pojo.User;
 import com.nokia.pojo.UserRoleCity;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Arrays;
 
 @SpringBootTest
 public class UserServiceTest {
@@ -42,7 +41,7 @@ public class UserServiceTest {
 
     @Test
     void testGetByLoginName() {
-        User user = userService.getByLoginName("test_abc");
+        User user = userDao.getByLoginName("test_abc");
         System.out.println(user);
     }