Commit 4765f9b9f2b70ba60b847e819dc5686e3bf23ed7

Authored by 648540858
2 parents 2b351e1e 1002150b

Merge remote-tracking branch 'origin/wvp-28181-2.0' into wvp-28181-2.0

src/main/java/com/genersoft/iot/vmp/service/IUserService.java
1 package com.genersoft.iot.vmp.service; 1 package com.genersoft.iot.vmp.service;
2 2
3 import com.genersoft.iot.vmp.storager.dao.dto.User; 3 import com.genersoft.iot.vmp.storager.dao.dto.User;
  4 +import com.github.pagehelper.PageInfo;
4 5
5 import java.util.List; 6 import java.util.List;
6 7
@@ -21,4 +22,8 @@ public interface IUserService { @@ -21,4 +22,8 @@ public interface IUserService {
21 int updateUsers(User user); 22 int updateUsers(User user);
22 23
23 boolean checkPushAuthority(String callId, String sign); 24 boolean checkPushAuthority(String callId, String sign);
  25 +
  26 + PageInfo<User> getUsers(int page, int count);
  27 +
  28 + int resetPushKey(int id);
24 } 29 }
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.service.impl; @@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.service.impl;
3 import com.genersoft.iot.vmp.service.IUserService; 3 import com.genersoft.iot.vmp.service.IUserService;
4 import com.genersoft.iot.vmp.storager.dao.UserMapper; 4 import com.genersoft.iot.vmp.storager.dao.UserMapper;
5 import com.genersoft.iot.vmp.storager.dao.dto.User; 5 import com.genersoft.iot.vmp.storager.dao.dto.User;
  6 +import com.github.pagehelper.PageHelper;
  7 +import com.github.pagehelper.PageInfo;
6 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
8 import org.springframework.util.StringUtils; 10 import org.springframework.util.StringUtils;
@@ -11,7 +13,7 @@ import java.util.List; @@ -11,7 +13,7 @@ import java.util.List;
11 13
12 @Service 14 @Service
13 public class UserServiceImpl implements IUserService { 15 public class UserServiceImpl implements IUserService {
14 - 16 +
15 @Autowired 17 @Autowired
16 private UserMapper userMapper; 18 private UserMapper userMapper;
17 19
@@ -64,4 +66,16 @@ public class UserServiceImpl implements IUserService { @@ -64,4 +66,16 @@ public class UserServiceImpl implements IUserService {
64 return userMapper.checkPushAuthorityByCallIdAndSign(callId, sign).size() > 0; 66 return userMapper.checkPushAuthorityByCallIdAndSign(callId, sign).size() > 0;
65 } 67 }
66 } 68 }
  69 +
  70 + @Override
  71 + public PageInfo<User> getUsers(int page, int count) {
  72 + PageHelper.startPage(page, count);
  73 + List<User> users = userMapper.getUsers();
  74 + return new PageInfo<>(users);
  75 + }
  76 +
  77 + @Override
  78 + public int resetPushKey(int id) {
  79 + return userMapper.resetPushKey(id);
  80 + }
67 } 81 }
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java
@@ -55,4 +55,11 @@ public interface UserMapper { @@ -55,4 +55,11 @@ public interface UserMapper {
55 55
56 @Select("select * from user where md5(pushKey) = '${sign}'") 56 @Select("select * from user where md5(pushKey) = '${sign}'")
57 List<User> checkPushAuthorityByCallId(String sign); 57 List<User> checkPushAuthorityByCallId(String sign);
  58 +
  59 + @Select("select u.idu.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")
  60 + @ResultMap(value="roleMap")
  61 + List<User> getUsers();
  62 +
  63 + @Delete("update user set pushKey=MD5(NOW()+#{id}) where id=#{id}")
  64 + int resetPushKey(int id);
58 } 65 }
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
@@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.storager.dao.dto.Role; @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.storager.dao.dto.Role;
8 import com.genersoft.iot.vmp.storager.dao.dto.User; 8 import com.genersoft.iot.vmp.storager.dao.dto.User;
9 import com.genersoft.iot.vmp.utils.DateUtil; 9 import com.genersoft.iot.vmp.utils.DateUtil;
10 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 10 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  11 +import com.github.pagehelper.PageInfo;
11 import io.swagger.annotations.Api; 12 import io.swagger.annotations.Api;
12 import io.swagger.annotations.ApiImplicitParam; 13 import io.swagger.annotations.ApiImplicitParam;
13 import io.swagger.annotations.ApiImplicitParams; 14 import io.swagger.annotations.ApiImplicitParams;
@@ -177,4 +178,67 @@ public class UserController { @@ -177,4 +178,67 @@ public class UserController {
177 result.setData(allUsers); 178 result.setData(allUsers);
178 return new ResponseEntity<>(result, HttpStatus.OK); 179 return new ResponseEntity<>(result, HttpStatus.OK);
179 } 180 }
  181 +
  182 + /**
  183 + * 分页查询用户
  184 + *
  185 + * @param page 当前页
  186 + * @param count 每页查询数量
  187 + * @return 分页用户列表
  188 + */
  189 + @ApiOperation("分页查询用户")
  190 + @ApiImplicitParams({
  191 + @ApiImplicitParam(name = "page", value = "当前页", required = true, dataTypeClass = Integer.class),
  192 + @ApiImplicitParam(name = "count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
  193 + })
  194 + @GetMapping("/users")
  195 + public PageInfo<User> users(int page, int count) {
  196 + return userService.getUsers(page, count);
  197 + }
  198 +
  199 + @ApiOperation("重置pushkey")
  200 + @ApiImplicitParams({
  201 + @ApiImplicitParam(name = "id", required = true, value = "用户Id", dataTypeClass = Integer.class),
  202 + })
  203 + @RequestMapping("/resetPushKey")
  204 + public ResponseEntity<WVPResult<String>> resetPushKey(@RequestParam Integer id) {
  205 + // 获取当前登录用户id
  206 + int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
  207 + WVPResult<String> result = new WVPResult<>();
  208 + if (currenRoleId != 1) {
  209 + // 只用角色id为0才可以删除和添加用户
  210 + result.setCode(-1);
  211 + result.setMsg("用户无权限");
  212 + return new ResponseEntity<>(result, HttpStatus.FORBIDDEN);
  213 + }
  214 + int resetPushKeyResult = userService.resetPushKey(id);
  215 +
  216 + result.setCode(resetPushKeyResult > 0 ? 0 : -1);
  217 + result.setMsg(resetPushKeyResult > 0 ? "success" : "fail");
  218 + return new ResponseEntity<>(result, HttpStatus.OK);
  219 + }
  220 +
  221 + @ApiOperation("管理员修改普通用户密码")
  222 + @ApiImplicitParams({
  223 + @ApiImplicitParam(name = "adminId", required = true, value = "管理员id", dataTypeClass = String.class),
  224 + @ApiImplicitParam(name = "userId", required = true, value = "用户id", dataTypeClass = String.class),
  225 + @ApiImplicitParam(name = "password", required = true, value = "新密码(未md5加密的密码)", dataTypeClass = String.class),
  226 + })
  227 + @PostMapping("/changePasswordForAdmin")
  228 + public String changePasswordForAdmin(@RequestParam int userId, @RequestParam String password) {
  229 + // 获取当前登录用户id
  230 + LoginUser userInfo = SecurityUtils.getUserInfo();
  231 + if (userInfo == null) {
  232 + return "fail";
  233 + }
  234 + Role role = userInfo.getRole();
  235 + if (role != null && role.getId() == 1) {
  236 + boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes()));
  237 + if (result) {
  238 + return "success";
  239 + }
  240 + }
  241 +
  242 + return "fail";
  243 + }
180 } 244 }
web_src/src/components/Login.vue
@@ -86,7 +86,7 @@ export default { @@ -86,7 +86,7 @@ export default {
86 }).then(function (res) { 86 }).then(function (res) {
87 console.log(JSON.stringify(res)); 87 console.log(JSON.stringify(res));
88 if (res.data.code == 0 && res.data.msg == "success") { 88 if (res.data.code == 0 && res.data.msg == "success") {
89 - that.$cookies.set("session", {"username": that.username}) ; 89 + that.$cookies.set("session", {"username": that.username,"roleId":res.data.data.role.id}) ;
90 //登录成功后 90 //登录成功后
91 that.cancelEnterkeyDefaultAction(); 91 that.cancelEnterkeyDefaultAction();
92 that.$router.push('/'); 92 that.$router.push('/');
web_src/src/components/UserManager.vue 0 → 100644
  1 +<template>
  2 +
  3 + <div id="app" style="width: 100%">
  4 + <div class="page-header">
  5 +
  6 + <div class="page-title">用户列表</div>
  7 + <div class="page-header-btn">
  8 + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addUser">
  9 + 添加用户
  10 + </el-button>
  11 +
  12 + </div>
  13 + </div>
  14 + <!--用户列表-->
  15 + <el-table :data="userList" style="width: 100%;font-size: 12px;" :height="winHeight"
  16 + header-row-class-name="table-header">
  17 + <el-table-column prop="username" label="用户名" min-width="160"/>
  18 + <el-table-column prop="pushKey" label="pushkey" min-width="160"/>
  19 + <el-table-column prop="role.name" label="类型" min-width="160"/>
  20 + <el-table-column label="操作" min-width="450" fixed="right">
  21 + <template slot-scope="scope">
  22 + <el-button size="medium" icon="el-icon-edit" type="text" @click="edit(scope.row)">修改密码</el-button>
  23 + <el-divider direction="vertical"></el-divider>
  24 + <el-button size="medium" icon="el-icon-refresh" type="text" @click="resetPushKey(scope.row)">重置pushkey</el-button>
  25 + <el-divider direction="vertical"></el-divider>
  26 + <el-button size="medium" icon="el-icon-delete" type="text" @click="deleteUser(scope.row)"
  27 + style="color: #f56c6c">删除
  28 + </el-button>
  29 + </template>
  30 + </el-table-column>
  31 + </el-table>
  32 + <changePasswordForAdmin ref="changePasswordForAdmin"></changePasswordForAdmin>
  33 + <addUser ref="addUser"></addUser>
  34 + <el-pagination
  35 + style="float: right"
  36 + @size-change="handleSizeChange"
  37 + @current-change="currentChange"
  38 + :current-page="currentPage"
  39 + :page-size="count"
  40 + :page-sizes="[15, 25, 35, 50]"
  41 + layout="total, sizes, prev, pager, next"
  42 + :total="total">
  43 + </el-pagination>
  44 + </div>
  45 +</template>
  46 +
  47 +<script>
  48 +import uiHeader from '../layout/UiHeader.vue'
  49 +import changePasswordForAdmin from './dialog/changePasswordForAdmin.vue'
  50 +import addUser from '../components/dialog/addUser.vue'
  51 +
  52 +export default {
  53 + name: 'userManager',
  54 + components: {
  55 + uiHeader,
  56 + changePasswordForAdmin,
  57 + addUser
  58 + },
  59 + data() {
  60 + return {
  61 + userList: [], //设备列表
  62 + currentUser: {}, //当前操作设备对象
  63 +
  64 + videoComponentList: [],
  65 + updateLooper: 0, //数据刷新轮训标志
  66 + currentUserLenth: 0,
  67 + winHeight: window.innerHeight - 200,
  68 + currentPage: 1,
  69 + count: 15,
  70 + total: 0,
  71 + getUserListLoading: false
  72 + };
  73 + },
  74 + mounted() {
  75 + this.initData();
  76 + this.updateLooper = setInterval(this.initData, 10000);
  77 + },
  78 + destroyed() {
  79 + this.$destroy('videojs');
  80 + clearTimeout(this.updateLooper);
  81 + },
  82 + methods: {
  83 + initData: function () {
  84 + this.getUserList();
  85 + },
  86 + currentChange: function (val) {
  87 + this.currentPage = val;
  88 + this.getUserList();
  89 + },
  90 + handleSizeChange: function (val) {
  91 + this.count = val;
  92 + this.getUserList();
  93 + },
  94 + getUserList: function () {
  95 + let that = this;
  96 + this.getUserListLoading = true;
  97 + this.$axios({
  98 + method: 'get',
  99 + url: `/api/user/users`,
  100 + params: {
  101 + page: that.currentPage,
  102 + count: that.count
  103 + }
  104 + }).then(function (res) {
  105 + that.total = res.data.total;
  106 + that.userList = res.data.list;
  107 + that.getUserListLoading = false;
  108 + }).catch(function (error) {
  109 + that.getUserListLoading = false;
  110 + });
  111 +
  112 + },
  113 + edit: function (row) {
  114 + this.$refs.changePasswordForAdmin.openDialog(row, () => {
  115 + this.$refs.changePasswordForAdmin.close();
  116 + this.$message({
  117 + showClose: true,
  118 + message: "密码修改成功",
  119 + type: "success",
  120 + });
  121 + setTimeout(this.getDeviceList, 200)
  122 +
  123 + })
  124 + },
  125 + deleteUser: function (row) {
  126 + let msg = "确定删除此用户?"
  127 + if (row.online !== 0) {
  128 + msg = "<strong>确定删除此用户?</strong>"
  129 + }
  130 + this.$confirm(msg, '提示', {
  131 + dangerouslyUseHTMLString: true,
  132 + confirmButtonText: '确定',
  133 + cancelButtonText: '取消',
  134 + center: true,
  135 + type: 'warning'
  136 + }).then(() => {
  137 + this.$axios({
  138 + method: 'delete',
  139 + url: `/api/user/delete?id=${row.id}`
  140 + }).then((res) => {
  141 + this.getUserList();
  142 + }).catch((error) => {
  143 + console.error(error);
  144 + });
  145 + }).catch(() => {
  146 +
  147 + });
  148 +
  149 +
  150 + },
  151 + resetPushKey: function (row) {
  152 + let msg = "确定重置pushkey?"
  153 + if (row.online !== 0) {
  154 + msg = "<strong>确定重置pushkey?</strong>"
  155 + }
  156 + this.$confirm(msg, '提示', {
  157 + dangerouslyUseHTMLString: true,
  158 + confirmButtonText: '确定',
  159 + cancelButtonText: '取消',
  160 + center: true,
  161 + type: 'warning'
  162 + }).then(() => {
  163 + this.$axios({
  164 + method: 'get',
  165 + url: `/api/user/resetPushKey?id=${row.id}`
  166 + }).then((res) => {
  167 + this.getUserList();
  168 + }).catch((error) => {
  169 + console.error(error);
  170 + });
  171 + }).catch(() => {
  172 +
  173 + });
  174 +
  175 +
  176 + },
  177 + addUser: function () {
  178 + this.$refs.addUser.openDialog()
  179 + }
  180 + }
  181 +}
  182 +</script>
  183 +<style>
  184 +.videoList {
  185 + display: flex;
  186 + flex-wrap: wrap;
  187 + align-content: flex-start;
  188 +}
  189 +
  190 +.video-item {
  191 + position: relative;
  192 + width: 15rem;
  193 + height: 10rem;
  194 + margin-right: 1rem;
  195 + background-color: #000000;
  196 +}
  197 +
  198 +.video-item-img {
  199 + position: absolute;
  200 + top: 0;
  201 + bottom: 0;
  202 + left: 0;
  203 + right: 0;
  204 + margin: auto;
  205 + width: 100%;
  206 + height: 100%;
  207 +}
  208 +
  209 +.video-item-img:after {
  210 + content: "";
  211 + display: inline-block;
  212 + position: absolute;
  213 + z-index: 2;
  214 + top: 0;
  215 + bottom: 0;
  216 + left: 0;
  217 + right: 0;
  218 + margin: auto;
  219 + width: 3rem;
  220 + height: 3rem;
  221 + background-image: url("../assets/loading.png");
  222 + background-size: cover;
  223 + background-color: #000000;
  224 +}
  225 +
  226 +.video-item-title {
  227 + position: absolute;
  228 + bottom: 0;
  229 + color: #000000;
  230 + background-color: #ffffff;
  231 + line-height: 1.5rem;
  232 + padding: 0.3rem;
  233 + width: 14.4rem;
  234 +}
  235 +
  236 +</style>
web_src/src/components/dialog/addUser.vue 0 → 100644
  1 +<template>
  2 + <div id="addUser" v-loading="isLoging">
  3 + <el-dialog
  4 + title="添加用户"
  5 + width="40%"
  6 + top="2rem"
  7 + :close-on-click-modal="false"
  8 + :visible.sync="showDialog"
  9 + :destroy-on-close="true"
  10 + @close="close()"
  11 + >
  12 + <div id="shared" style="margin-right: 20px;">
  13 + <el-form ref="passwordForm" :rules="rules" status-icon label-width="80px">
  14 + <el-form-item label="用户名" prop="username">
  15 + <el-input v-model="username" autocomplete="off"></el-input>
  16 + </el-form-item>
  17 + <el-form-item label="用户类型" prop="roleId">
  18 + <el-select v-model="roleId" placeholder="请选择">
  19 + <el-option
  20 + v-for="item in options"
  21 + :key="item.id"
  22 + :label="item.name"
  23 + :value="item.id">
  24 + </el-option>
  25 + </el-select>
  26 + </el-form-item>
  27 + <el-form-item label="密码" prop="password">
  28 + <el-input v-model="password" autocomplete="off"></el-input>
  29 + </el-form-item>
  30 + <el-form-item label="确认密码" prop="confirmPassword">
  31 + <el-input v-model="confirmPassword" autocomplete="off"></el-input>
  32 + </el-form-item>
  33 +
  34 + <el-form-item>
  35 + <div style="float: right;">
  36 + <el-button type="primary" @click="onSubmit">保存</el-button>
  37 + <el-button @click="close">取消</el-button>
  38 + </div>
  39 + </el-form-item>
  40 + </el-form>
  41 + </div>
  42 + </el-dialog>
  43 + </div>
  44 +</template>
  45 +
  46 +<script>
  47 +
  48 +export default {
  49 + name: "addUser",
  50 + props: {},
  51 + computed: {},
  52 + created() {
  53 + this.getAllRole();
  54 + },
  55 + data() {
  56 + let validatePass1 = (rule, value, callback) => {
  57 + if (value === '') {
  58 + callback(new Error('请输入新密码'));
  59 + } else {
  60 + if (this.confirmPassword !== '') {
  61 + this.$refs.passwordForm.validateField('confirmPassword');
  62 + }
  63 + callback();
  64 + }
  65 + };
  66 + let validatePass2 = (rule, value, callback) => {
  67 + if (this.confirmPassword === '') {
  68 + callback(new Error('请再次输入密码'));
  69 + } else if (this.confirmPassword !== this.password) {
  70 + callback(new Error('两次输入密码不一致!'));
  71 + } else {
  72 + callback();
  73 + }
  74 + };
  75 + return {
  76 + value:"",
  77 + options: [],
  78 + loading: false,
  79 + username: null,
  80 + password: null,
  81 + roleId: null,
  82 + confirmPassword: null,
  83 + listChangeCallback: null,
  84 + showDialog: false,
  85 + isLoging: false,
  86 + rules: {
  87 + newPassword: [{required: true, validator: validatePass1, trigger: "blur"}, {
  88 + pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/]).{8,20}$/,
  89 + message: "密码长度在8-20位之间,由字母+数字+特殊字符组成",
  90 + },],
  91 + confirmPassword: [{required: true, validator: validatePass2, trigger: "blur"}],
  92 + },
  93 + };
  94 + },
  95 + methods: {
  96 + openDialog: function (callback) {
  97 + this.listChangeCallback = callback;
  98 + this.showDialog = true;
  99 + },
  100 + onSubmit: function () {
  101 + this.$axios({
  102 + method: 'post',
  103 + url: "/api/user/add",
  104 + params: {
  105 + username: this.username,
  106 + password: this.password,
  107 + roleId: this.roleId
  108 + }
  109 + }).then((res) => {
  110 + if (res.data.code === 0) {
  111 + this.$message({
  112 + showClose: true,
  113 + message: '添加成功',
  114 + type: 'success',
  115 +
  116 + });
  117 + this.showDialog = false;
  118 + this.listChangeCallback()
  119 +
  120 + } else {
  121 + this.$message({
  122 + showClose: true,
  123 + message: res.data.msg,
  124 + type: 'error'
  125 + });
  126 + }
  127 + }).catch((error) => {
  128 + console.error(error)
  129 + });
  130 + },
  131 + close: function () {
  132 + this.showDialog = false;
  133 + this.password = null;
  134 + this.confirmPassword = null;
  135 + this.username = null;
  136 + this.roleId = null;
  137 + },
  138 + getAllRole:function () {
  139 +
  140 + this.$axios({
  141 + method: 'get',
  142 + url: "/api/role/all"
  143 + }).then((res) => {
  144 + this.loading = true;
  145 + console.info(res)
  146 + res.data
  147 + console.info(res.data.code)
  148 + if (res.data.code === 0) {
  149 + console.info(res.data.data)
  150 + this.options=res.data.data
  151 +
  152 + }
  153 + }).catch((error) => {
  154 + console.error(error)
  155 + });
  156 + }
  157 + },
  158 +};
  159 +</script>
web_src/src/components/dialog/changePasswordForAdmin.vue 0 → 100644
  1 +<template>
  2 + <div id="changePassword" v-loading="isLoging">
  3 + <el-dialog
  4 + title="修改密码"
  5 + width="40%"
  6 + top="2rem"
  7 + :close-on-click-modal="false"
  8 + :visible.sync="showDialog"
  9 + :destroy-on-close="true"
  10 + @close="close()"
  11 + >
  12 + <div id="shared" style="margin-right: 20px;">
  13 + <el-form ref="passwordForm" :rules="rules" status-icon label-width="80px">
  14 + <el-form-item label="新密码" prop="newPassword" >
  15 + <el-input v-model="newPassword" autocomplete="off"></el-input>
  16 + </el-form-item>
  17 + <el-form-item label="确认密码" prop="confirmPassword">
  18 + <el-input v-model="confirmPassword" autocomplete="off"></el-input>
  19 + </el-form-item>
  20 +
  21 + <el-form-item>
  22 + <div style="float: right;">
  23 + <el-button type="primary" @click="onSubmit">保存</el-button>
  24 + <el-button @click="close">取消</el-button>
  25 + </div>
  26 + </el-form-item>
  27 + </el-form>
  28 + </div>
  29 + </el-dialog>
  30 + </div>
  31 +</template>
  32 +
  33 +<script>
  34 +export default {
  35 + name: "changePasswordForAdmin",
  36 + props: {},
  37 + computed: {},
  38 + created() {},
  39 + data() {
  40 + let validatePass1 = (rule, value, callback) => {
  41 + if (value === '') {
  42 + callback(new Error('请输入新密码'));
  43 + } else {
  44 + if (this.confirmPassword !== '') {
  45 + this.$refs.passwordForm.validateField('confirmPassword');
  46 + }
  47 + callback();
  48 + }
  49 + };
  50 + let validatePass2 = (rule, value, callback) => {
  51 + if (this.confirmPassword === '') {
  52 + callback(new Error('请再次输入密码'));
  53 + } else if (this.confirmPassword !== this.newPassword) {
  54 + callback(new Error('两次输入密码不一致!'));
  55 + } else {
  56 + callback();
  57 + }
  58 + };
  59 + return {
  60 + newPassword: null,
  61 + confirmPassword: null,
  62 + userId: null,
  63 + showDialog: false,
  64 + isLoging: false,
  65 + listChangeCallback: null,
  66 + form: {},
  67 + rules: {
  68 + newPassword: [{ required: true, validator: validatePass1, trigger: "blur" }, {
  69 + pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/]).{8,20}$/,
  70 + message: "密码长度在8-20位之间,由字母+数字+特殊字符组成",
  71 + },],
  72 + confirmPassword: [{ required: true, validator: validatePass2, trigger: "blur" }],
  73 + },
  74 + };
  75 + },
  76 + methods: {
  77 + openDialog: function (row, callback) {
  78 + console.log(row)
  79 + this.showDialog = true;
  80 + this.listChangeCallback = callback;
  81 + if (row != null) {
  82 + this.form = row;
  83 + }
  84 + },
  85 + onSubmit: function () {
  86 + this.$axios({
  87 + method: 'post',
  88 + url:"/api/user/changePasswordForAdmin",
  89 + params: {
  90 + password: this.newPassword,
  91 + userId: this.form.id,
  92 + }
  93 + }).then((res)=> {
  94 + if (res.data === "success"){
  95 + this.$message({
  96 + showClose: true,
  97 + message: '修改成功',
  98 + type: 'success'
  99 + });
  100 + this.showDialog = false;
  101 + }else {
  102 + this.$message({
  103 + showClose: true,
  104 + message: '修改密码失败,是否已登录(接口鉴权关闭无法修改密码)',
  105 + type: 'error'
  106 + });
  107 + }
  108 + }).catch((error)=> {
  109 + console.error(error)
  110 + });
  111 + },
  112 + close: function () {
  113 + this.showDialog = false;
  114 + this.newPassword = null;
  115 + this.confirmPassword = null;
  116 + this.userId=null;
  117 + this.adminId=null;
  118 + },
  119 + },
  120 +};
  121 +</script>
web_src/src/layout/UiHeader.vue
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 <el-menu-item index="/cloudRecord">云端录像</el-menu-item> 13 <el-menu-item index="/cloudRecord">云端录像</el-menu-item>
14 <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> 14 <el-menu-item index="/mediaServerManger">节点管理</el-menu-item>
15 <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> 15 <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item>
  16 + <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item>
16 17
17 <!-- <el-submenu index="/setting">--> 18 <!-- <el-submenu index="/setting">-->
18 <!-- <template slot="title">系统设置</template>--> 19 <!-- <template slot="title">系统设置</template>-->
@@ -47,9 +48,11 @@ export default { @@ -47,9 +48,11 @@ export default {
47 alarmNotify: false, 48 alarmNotify: false,
48 sseSource: null, 49 sseSource: null,
49 activeIndex: this.$route.path, 50 activeIndex: this.$route.path,
  51 + editUser: this.$cookies.get("session").roleId==1
50 }; 52 };
51 }, 53 },
52 created() { 54 created() {
  55 + console.log(this.$cookies.get("session"))
53 if (this.$route.path.startsWith("/channelList")) { 56 if (this.$route.path.startsWith("/channelList")) {
54 this.activeIndex = "/deviceList" 57 this.activeIndex = "/deviceList"
55 } 58 }
web_src/src/router/index.js
@@ -17,6 +17,7 @@ import sip from &#39;../components/setting/Sip.vue&#39; @@ -17,6 +17,7 @@ import sip from &#39;../components/setting/Sip.vue&#39;
17 import media from '../components/setting/Media.vue' 17 import media from '../components/setting/Media.vue'
18 import live from '../components/live.vue' 18 import live from '../components/live.vue'
19 import deviceTree from '../components/common/DeviceTree.vue' 19 import deviceTree from '../components/common/DeviceTree.vue'
  20 +import userManager from '../components/UserManager.vue'
20 21
21 import wasmPlayer from '../components/common/jessibuca.vue' 22 import wasmPlayer from '../components/common/jessibuca.vue'
22 import rtcPlayer from '../components/dialog/rtcPlayer.vue' 23 import rtcPlayer from '../components/dialog/rtcPlayer.vue'
@@ -103,6 +104,11 @@ export default new VueRouter({ @@ -103,6 +104,11 @@ export default new VueRouter({
103 name: 'map', 104 name: 'map',
104 component: map, 105 component: map,
105 }, 106 },
  107 + {
  108 + path: '/userManager',
  109 + name: 'userManager',
  110 + component: userManager,
  111 + }
106 ] 112 ]
107 }, 113 },
108 { 114 {